php-ffmpeg get video duration - ffmpeg

When I try to get the duration of a video using the php-ffmpeg wrapper and ffprobe, I get a huge object instead of just the duration.
$ffprobe = FFMpeg\FFProbe::create();
$ffprobe->format($this->videoFile)
->get('duration');
$this->videoFile is /home/admin/........./5422346433.mp4
So it points to right file and the duration is listed in the giant object down in
[[-show_format-/home/admin/web/admin.simplewebevents.com/public_html/cron/649652027.mp4][1]] => Array
(
[0] => FFMpeg\FFProbe\DataMapping\Format Object
(
[properties:FFMpeg\FFProbe\DataMapping\AbstractData:private] => Array
(
[filename] => /home/admin/web/admin.simplewebevents.com/public_html/cron/649652027.mp4
[nb_streams] => 2
[nb_programs] => 0
[format_name] => mov,mp4,m4a,3gp,3g2,mj2
[format_long_name] => QuickTime / MOV
[start_time] => 0.000000
[duration] => 5736.833333
[size] => 668381267
[bit_rate] => 932056
[probe_score] => 100
[tags] => Array
(
[major_brand] => mp42
[minor_version] => 0
[compatible_brands] => mp42mp41isomavc1
[creation_time] => 2016-12-04 18:25:58
)
)
)
[1] =>
)
)
But apparently ->get('duration') doesnt return the duration.
I've also tried with
$ffprobe
->streams($this->videoFile) // extracts streams informations
->videos() // filters video streams
->first() // returns the first video stream
->get('duration');

$ffprobe
->streams($this->videoFile)
->videos()
->first()
->get('duration');
RETURNS the duration. So I have to store that command into a variable. The correct way to get the duration is:
$duration = $ffprobe
->streams($this->videoFile)
->videos()
->first()
->get('duration');

in the README.md is write this code:
$ffprobe = FFMpeg\FFProbe::create();
$duration = $ffprobe
->format('/path/to/video/mp4') // extracts file informations
->get('duration'); // returns the duration property
and work fine.

$file='msd.mp4';
$time = exec("$ffmpeg -i ".$file." 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//");
echo getSecondsFromHMS($time);
function getSecondsFromHMS($time) {
$timeArr = array_reverse(explode(":", $time));
$seconds = 0;
echo '<pre>';print_r($timeArr);echo '</pre>';
foreach ($timeArr as $key => $value) {
if ($key > 2)
break;
$seconds += pow(60, $key) * $value;
}
return (int)$seconds;
}
It is the return duration in seconds.

if anyone don't wanted to use ffmpeg-php then use following code
$file='http://techslides.com/demos/sample-videos/small.mp4';
$dur = shell_exec("ffmpeg -i ".$file." 2>&1");
if(preg_match("/: Invalid /", $dur)){
return false;
}
preg_match("/Duration: (.{2}):(.{2}):(.{2})/", $dur, $duration);
if(!isset($duration[1])){
return false;
}
$hours = $duration[1];
$minutes = $duration[2];
$seconds = $duration[3];
echo $seconds + ($minutes*60) + ($hours*60*60);
Reference

Related

How to loop number and saved into table laravel

I have input and this input is will generate number sequentially like this
5.01
5.02
5.03
......
5.10
5.11
i get number 5 on first number is from my another data . u can see at my code .so how i can do this if this number start from '01' not '1' and if more than 10 this '0' in first number is deleted.
in my controller i saved in $data and looping this number from 01
So in my input controller is like that :
public function store(Request $request)
{
$data = $request['kode_induk'] + // i dont know what to do here for loop this input ,
$induk = IndukBelanja::create([
'user_id' => Auth::user()->id,
'kode_induk' => $request['kode_induk'],
'kode_rekening' => $data,
'uraian' => $request['uraian'],
'anggaran' => $request['anggaran'],
]);
if ($induk) {
return ['redirect' => route('rekening_induk')];
} else {
return response()->json([
'success' => false,
'message' => ' Gagal update!',
], 500);
}
}
how i can loop this number ? can someone help ?
Update its my database what i need
+----+------------+------------+------------+
| id |kode_induk |kode_rekening| uraian
+----+------------+------------+------------+
| 1 | 5 | 5.01 | some data
+----+------------+------------+------------+
| 2 | 5 | 5.02 | some data
+----+------------+------------+------------+
| 3 | 5 | 5.03 | some data
+----+------------+------------+------------+
| 4 | 5 | 5.04 | some data
+----+------------+------------+------------+
You can cast $data to int and then increment by 0.01 in a for loop.
$data = (int) $request['kode_induk'];
$numberOfSequencesToGenerate = 10;
for($i = 0; $i < $numberOfSequencesToGenerate; $++){
$induk = IndukBelanja::create([
'user_id' => Auth::user()->id,
'kode_induk' => $request['kode_induk'],
'kode_rekening' => $data + 0.01,
'uraian' => $request['uraian'],
'anggaran' => $request['anggaran'],
]);
}
The loop basically reads, run the the block of code while $i is less than $numberOfSequencesToGenerate. On each iteration increment $i by one.
I am assuming the DB field kode_rekening is of type double but if is not you can format it in PHP so is always has two decimal places with number_format(). Ex: number_format($data + 0.01, 2)

How to merge multiple arrays in PHP and output the values together?

I have a situation while developing an application on Laravel. I have three arrays in the following order. I need to merge them and display their values in the following order too. Here , it goes.
stone_name['ruby','diamond','catseye'];
stone_weight[112,223,445];
stone_rate[1000,2500,670];
I need to merge these three arrays and display the out put in this order.
stone_info = array(stone_name[0] , stone_weight[0] , stone_rate[0]);
So that the final result will be like :
stone_info = array("ruby",112,1000);
I was in the same situation and I had done it in this way. May be this can help you out.
<?php
$stone_name = ['ruby','diamond','catseye'];
$stone_weight = [112,223,445];
$stone_rate = [1000,2500,670];
$result = mergeArrays($stone_name, $stone_weight, $stone_rate);
function mergeArrays($stone_name, $stone_weight, $stone_rate) {
$result = array();
foreach ($stone_name as $key => $name ) {
$result[] = array( 'stone_name' => $name, 'stone_weight' => $stone_weight[$key], 'stone_rate' => $stone_rate[ $key ] );
}
return $result;
}
print_r($result);
Output:
Array
(
[0] => Array
(
[stone_name] => ruby
[stone_weight] => 112
[stone_rate] => 1000
)
[1] => Array
(
[stone_name] => diamond
[stone_weight] => 223
[stone_rate] => 2500
)
[2] => Array
(
[stone_name] => catseye
[stone_weight] => 445
[stone_rate] => 670
)
)
DEMO

Codeigniter Calendar : Adding Specific Data to A Cell

Here is my problem,
I need to show all the people with birthdays with the selected month, I already got on how to put the data on the specific, table cells, the only problem is that the data is also appearing on other tables cells which it is not intended. On the figure below Ori Hendricks must only be on 2 but it appears on other cells.
Here is the data for the calendar
Array
(
[2] => Array
(
[0] => Nomlanga Bentley**81
[1] => Ori Hendricks**325
)
[5] => Array
(
[0] => Rina Nash**161
)
[10] => Array
(
[0] => Gary Mullins**252
)
[12] => Array
(
[0] => Nissim Donovan**207
)
[13] => Array
(
[0] => Harper Trevino**380
)
[14] => Array
(
[0] => Sacha Arnold**167
[1] => Wade Hughes**322
[2] => Brennan Long**3
)
[15] => Array
(
[0] => Gary Hart**290
)
[21] => Array
(
[0] => Alisa Bowman**201
)
[22] => Array
(
[0] => Dustin Meyers**330
)
[26] => Array
(
[0] => Ifeoma Swanson**331
)
[28] => Array
(
[0] => McKenzie Norton**327
[1] => Asher Rasmussen**47
)
[29] => Array
(
[0] => Branden Conway**7
[1] => Luke Sullivan**176
)
[30] => Array
(
[0] => Slade Moon**16
)
)
Iv'e created a MY_calendar class and created my own generator,here is the relevant code for showing the data on the cells
if (isset($data[$day]))
{
// Cells with content
$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
if(is_array($data[$day]))
{
foreach($data[$day] as $k => $v)
{
$name = substr($v,0,strpos($v,'**'));
$student_enrollment_id = substr($v,strpos($v,'**')+2);
$data_formatted[$k] = ''.trim($name).'';
}
$data_from_array = implode('',$data_formatted);
$out .= str_replace('{day}', $day, str_replace('{content}', $data_from_array, $temp));
}else{
$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
}
}
else
{
// Cells with no content
$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
$out .= str_replace('{day}', $day, $temp);
}
i don't have any other idea how to do this, please help.
The issue is happening because the array indexes are still holding the values from the last loop.
Just make this slight change in MY_calendar class code snippet you have pasted above:
<?php
if (isset($data[$day]))
{
// Cells with content
$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content'];
if(is_array($data[$day]))
{
foreach($data[$day] as $k => $v)
{
$name = substr($v,0,strpos($v,'**'));
$student_enrollment_id = substr($v,strpos($v,'**')+2);
$data_formatted[$k] = ''.trim($name).'';
}
$data_from_array = implode('',$data_formatted);
$out .= str_replace('{day}', $day, str_replace('{content}', $data_from_array, $temp));
$data_formatted = array_fill(0,count($data_formatted), null); // line added to reset the values in previous loop
}else{
$out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp));
}
}
else
{
// Cells with no content
$temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_no_content_today'] : $this->temp['cal_cell_no_content'];
$out .= str_replace('{day}', $day, $temp);
}
This should fix the issue.

Display "time ago" instead of datetime in PHP Codeigniter

I would like to display a time format like twitter and FB (Posted 3 hours ago, Posted 2 minutes ago and so on...)
I've tried this piece of code without success :
function format_interval($timestamp, $granularity = 2) {
$units = array('1 year|#count years' => 31536000, '1 week|#count weeks' => 604800, '1 day|#count days' => 86400, '1 hour|#count hours' => 3600, '1 min|#count min' => 60, '1 sec|#count sec' => 1);
$output = '';
foreach ($units as $key => $value) {
$key = explode('|', $key);
if ($timestamp >= $value) {
$floor = floor($timestamp / $value);
$output .= ($output ? ' ' : '') . ($floor == 1 ? $key[0] : str_replace('#count', $floor, $key[1]));
$timestamp %= $value;
$granularity--;
}
if ($granularity == 0) {
break;
}
}
I use this function with a callback into another function like : $this->format_interval(); and pass it to my View
My current format date is : 2012-07-26 09:31:pm and already stored in my DB
Any help will be very appreciated!
The Date Helper's timespan() method just does that:
The most common purpose for this function is to show how much time has elapsed from some point in time in the past to now.
Given a timestamp, it will show how much time has elapsed in this format:
1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes
So, in your example, all you need to do is convert your date to a timestamp and do something like this:
$post_date = '13436714242';
$now = time();
// will echo "2 hours ago" (at the time of this post)
echo timespan($post_date, $now) . ' ago';
Try something like this in a my_date_helper.php file (source: Codeigniter Forums):
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if( ! function_exists('relative_time'))
{
function relative_time($datetime)
{
$CI =& get_instance();
$CI->lang->load('date');
if(!is_numeric($datetime))
{
$val = explode(" ",$datetime);
$date = explode("-",$val[0]);
$time = explode(":",$val[1]);
$datetime = mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
}
$difference = time() - $datetime;
$periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade");
$lengths = array("60","60","24","7","4.35","12","10");
if ($difference > 0)
{
$ending = $CI->lang->line('date_ago');
}
else
{
$difference = -$difference;
$ending = $CI->lang->line('date_to_go');
}
for($j = 0; $difference >= $lengths[$j]; $j++)
{
$difference /= $lengths[$j];
}
$difference = round($difference);
if($difference != 1)
{
$period = strtolower($CI->lang->line('date_'.$periods[$j].'s'));
} else {
$period = strtolower($CI->lang->line('date_'.$periods[$j]));
}
return "$difference $period $ending";
}
}
The format is a little different than the one you're using in your database (why do you mark times with pm/am rather than just use 24 hour times and convert for the frontend?). Either way, shouldn't take much work to get it working.
I had a function that solved this like this:
$int_diff = (time() - $int_time);
$str_this_year = date('Y-01-01', $int_time);
$str_weekday = t('time_weekday_'.strtolower(date('l', $int_time)));
$str_month = t('time_month_'.strtolower(date('F', $int_time)));
$arr_time_formats = array( '-90 seconds' => t('time_a_minute_at_most'),
'-45 minutes' => t('time_minutes_ago', ceil($int_diff / (60))),
'-70 minutes' => t('time_an_hour_at_most'),
'-8 hours' => t('time_hours_ago', ceil($int_diff / (60 * 60))),
'today' => t('time_hours_ago', ceil($int_diff / (60 * 60))),
'yesterday' => t('time_yesterday', date('H:i', $int_time)),
'-4 days' => t('time_week_ago', $str_weekday, date('H:i', $int_time)),
$str_this_year => t('time_date', date('j', $int_time), $str_month, date('H:i', $int_time)),
0 => t('time_date_year', date('j', $int_time), $str_month, date('Y', $int_time), date('H:i', $int_time)));
if ($boo_whole)
return $arr_time_formats[0];
foreach(array_keys($arr_time_formats) as $h)
if ($int_time >= strtotime($h))
return $arr_time_formats[$h];
Basicly t() is a function combined with $this->lang->line() and sprintf(). The idea here is to give keys that's runned through strtotime() till you reach the closest time, with 0 being the fallback.
This approach is really good since you can easy adjust the times with a nice overview. I could give more piece of the code, but it feels like doing too much of the work :) Basicly this is just the theory behind how you can do it.
<?php
$this->load->helper('date');
//client created date get from database
$date=$client_list->created_date;
// Declare timestamps
$last = new DateTime($date);
$now = new DateTime( date( 'Y-m-d h:i:s', time() )) ;
// Find difference
$interval = $last->diff($now);
// Store in variable to be used for calculation etc
$years = (int)$interval->format('%Y');
$months = (int)$interval->format('%m');
$days = (int)$interval->format('%d');
$hours = (int)$interval->format('%H');
$minutes = (int)$interval->format('%i');
// $now = date('Y-m-d H:i:s');
if($years > 0)
{
echo $years.' Years '.$months.' Months '.$days.' Days '. $hours.' Hours '.$minutes.' minutes ago.' ;
}
else if($months > 0)
{
echo $months.' Months '.$days.' Days '. $hours.' Hours '.$minutes.' minutes ago.' ;
}
else if($days > 0)
{
echo $days.' Days '.$hours.' Hours '.$minutes.' minutes ago.' ;
}
else if($hours > 0)
{
echo $hours.' Hours '.$minutes.' minutes ago.' ;
}
else
{
echo $minutes.' minutes ago.' ;
}
?>

calculate duration for the given set of timestamp

I have a set of intime and outtime, and i want to calculate the duration between the intime and outtime and add all the duration to get the total duration.
example:
Array
(
[1] => Array
(
['intime'] => 1342086993
['outime'] => 1342087585
)
[3] => Array
(
['intime'] => 1342087669
['outtime] => 1342096165
)
[5] => Array
(
['intime'] => 1342096339
['outime'] => 1342096345
)
)
$total_duration = 0;
foreach($logArray as $log)
{
$duration = $log['outime'] - $log['intime'];
$total_duration += $duration;
}
$duration_hrs = $total_duration/3600;
echo 'Time spend in hrs :'.$duration_hrs;
but this is not giving me the proper duration. is there any other way to do so.
Use array_map to first map each element to the duration, and then array_sum to sum them:
$durations = array_map(function ($e) {
return $e['outtime'] - $e['intime'];
}, $logArray);
$total_duration = array_sum($durations);
Your syntax free script, works for me fine:
<?php
$logArray = Array (
1 => Array (
'intime' => 1342086993,
'outime' => 1342087585
),
3 => Array (
'intime' => 1342087669,
'outime' => 1342096165
),
5 => Array (
'intime' => 1342096339,
'outime' => 1342096345
)
);
$total_duration = 0;
foreach( $logArray as $log ) {
$duration = $log[ 'outime' ] - $log[ 'intime' ];
$total_duration += $duration;
echo $duration / 3600 . "<br />";
}
$duration_hrs = $total_duration / 3600;
echo 'Time spend in hrs: ' . $duration_hrs;
?>
And the output:
0.16444444444444
2.36
0.0016666666666667
Time spend in hrs: 2.5261111111111
Seems like your time format is not right: 13, July 2012 04:04:32 PM should be 13. July 2012 04:04:32 PM for
strtotime('13. July 2012 04:04:32 PM')
to work right. It should give 1342195472 instead of you 1342168834. So check your time formats that are generating wrong microtimes
$total_duration = 0;
foreach($logArray as $log)
{
$duraton = $log['outtime'] - $log['intime'];
$total_duration += $duration;
}
$duration_hrs = $total_duration/3600;
echo 'Time spend in hrs :'.$duration_hrs;
you have a simple typo in your code. check that:
duraton vs duration
change and will be fine.

Resources