Skip to content

Instantly share code, notes, and snippets.

@petrkle
Created February 20, 2020 10:56
Show Gist options
  • Save petrkle/0a269ae22e46f4373ef360a4b55c3543 to your computer and use it in GitHub Desktop.
Save petrkle/0a269ae22e46f4373ef360a4b55c3543 to your computer and use it in GitHub Desktop.
Join 3 minutes chunks from dashcam to mkv file.
#!/usr/bin/php
<?php
define("WORK", '/tmp/'.basename(__FILE__).'.processing');
declare(ticks = 1);
pcntl_signal(SIGTERM, 'signalHandler');// Termination ('kill' was called)
pcntl_signal(SIGHUP, 'signalHandler'); // Terminal log-out
pcntl_signal(SIGINT, 'signalHandler'); // Interrupted (Ctrl-C is pressed)
$pidFileName = basename(__FILE__) . '.pid';
$pidFile = @fopen($pidFileName, 'c');
if (!$pidFile) die("Could not open $pidFileName\n");
if (!@flock($pidFile, LOCK_EX | LOCK_NB)) die("Already running?\n");
ftruncate($pidFile, 0);
fwrite($pidFile, getmypid());
function signalHandler($signal) {
global $pidFile;
ftruncate($pidFile, 0);
if(is_file(WORK)){
unlink(file_get_contents(WORK));
}
exit;
}
$in = "/run/media/sdcard/Video/F";
$out = "/home/data/dashcam";
$suffix = '.MP4';
$split = 180; # sec
$splittolerance = 10; # sec
$chunks = glob("$in/*$suffix");
asort($chunks);
$parts = array();
$part = 0;
$prevtime = 0;
foreach($chunks as $filename){
$file = basename($filename, $suffix);
$time = filename2time($file);
if($prevtime > 0){
$diff = $time - $prevtime;
if($diff > ($split-$splittolerance) and $diff < ($split+$splittolerance)){
if(!is_array($parts[$part]['files'])){
$parts[$part]['files'] = array();
}
array_push($parts[$part]['files'], $filename);
}else{
$part++;
$parts[$part]['files'] = array();
array_push($parts[$part]['files'], $filename);
}
}else{
$parts[$part]['files'] = array();
array_push($parts[$part]['files'], $filename);
}
$prevtime = $time;
}
foreach($parts as $part){
if(count($part['files']) > 1){
$from = filename2time(basename($part['files'][0], $suffix));
$from_hr = date('Y-m-d-Hi', $from);
$fromday = date('Y-m-d', $from);
$to = filename2time(basename($part['files'][count($part['files'])-1], $suffix));
$today = date('Y-m-d', $to);
if($fromday == $today){
$to_hr = date('Hi', $to);
}else{
$to_hr = date('Y-m-d-Hi', $to);
}
$video = "$out/$from_hr-$to_hr.mkv";
if(!is_file($video)){
$tmpfname = tempnam("/tmp", __FILE__);
$fp = fopen($tmpfname, 'w');
foreach($part['files'] as $file){
fwrite($fp, "file '$file'\n");
print "$file\n";
}
fclose($fp);
file_put_contents(WORK, $video);
print "$video\n";
system("ffmpeg -loglevel error -safe 0 -f concat -i $tmpfname -vcodec copy -an $video");
print human_filesize(filesize($video))."\n";
unlink(WORK);
unlink($tmpfname);
}
}
}
function filename2time($file){
$year = '20'.substr($file, 4, 2);
$month = substr($file, 6, 2);
$day = substr($file, 8, 2);
$hour = substr($file, 11, 2);
$min = substr($file, 13, 2);
$sec = substr($file, 15, 2);
return strtotime("$year-$month-$day $hour:$min:$sec");
}
function human_filesize($bytes, $decimals = 1) {
$sz = 'BKMGTP';
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment