diff --git a/inc/lib/webm/ffmpeg.php b/inc/lib/webm/ffmpeg.php index f62bfced..810c68c1 100644 --- a/inc/lib/webm/ffmpeg.php +++ b/inc/lib/webm/ffmpeg.php @@ -5,17 +5,18 @@ */ function get_webm_info($filename) { - global $board, $config; + global $config; + $filename = escapeshellarg($filename); $ffprobe = $config['webm']['ffprobe_path']; - $ffprobe_out = array(); - $webminfo = array(); + $ffprobe_out = []; + $webminfo = []; exec("$ffprobe -v quiet -print_format json -show_format -show_streams $filename", $ffprobe_out); $ffprobe_out = json_decode(implode("\n", $ffprobe_out), 1); $validcheck = is_valid_webm($ffprobe_out); $webminfo['error'] = $validcheck['error']; - if(empty($webminfo['error'])) { + if (empty($webminfo['error'])) { $trackmap = $validcheck['trackmap']; $videoidx = $trackmap['videoat'][0]; $webminfo['width'] = $ffprobe_out['streams'][$videoidx]['width']; @@ -26,97 +27,131 @@ function get_webm_info($filename) { } function locate_webm_tracks($ffprobe_out) { - $streams = $ffprobe_out['streams']; - $streamcount = count($streams); - $videoat = array(); - $audioat = array(); - $others = array(); + $streams = $ffprobe_out['streams']; + $streamcount = count($streams); + $video_at = []; + $audio_at = []; + $others = []; - for ($k = 0; $k < $streamcount; $k++) { - $stream = $streams[$k]; - $codec_type = $stream['codec_type']; + for ($k = 0; $k < $streamcount; $k++) { + $stream = $streams[$k]; + $codec_type = $stream['codec_type']; - if ($codec_type === 'video') { - $videoat[] = $k; - } elseif($codec_type === 'audio') { - $audioat[] = $k; - } else { - if (isset($others[$codec_type])) { - $others[$codec_type][] = $k; - } else { - $others[$codec_type] = [$k]; - } - } - } + if ($codec_type === 'video') { + $video_at[] = $k; + } elseif ($codec_type === 'audio') { + $audio_at[] = $k; + } else { + if (isset($others[$codec_type])) { + $others[$codec_type][] = $k; + } else { + $others[$codec_type] = [$k]; + } + } + } - return array('videoat' => $videoat, 'audioat' => $audioat, 'others' => $others); -/* -var_dump example: -array(3) { - ["videoat"]=> array(1) { - [0]=> int(0) - } - ["audioat"]=> array(1) { - [0]=> int(1) - } - ["others"]=> array(1) { - ["data"]=> array(2) { - [0]=> int(2) - [1]=> int(3) - } - } -} - */ + return [ 'videoat' => $video_at, 'audioat' => $audio_at, 'others' => $others ]; } function is_valid_webm($ffprobe_out) { - global $board, $config; - if (empty($ffprobe_out)) - return array('error' => array('code' => 1, 'msg' => $config['error']['genwebmerror'])); + global $config; + + if (empty($ffprobe_out)) { + return [ 'error' => [ 'code' => 1, 'msg' => $config['error']['genwebmerror'] ] ]; + } $trackmap = locate_webm_tracks($ffprobe_out); // one video track - if (count($trackmap['videoat']) != 1) - return array('error' => array('code' => 2, 'msg' => $config['error']['invalidwebm']." [video track count]")); + if (count($trackmap['videoat']) != 1) { + return [ + 'error' => [ + 'code' => 2, + 'msg' => $config['error']['invalidwebm'] . ' [video track count]' + ] + ]; + } $videoidx = $trackmap['videoat'][0]; $extension = pathinfo($ffprobe_out['format']['filename'], PATHINFO_EXTENSION); if ($extension === 'webm' && !stristr($ffprobe_out['format']['format_name'], 'mp4')) { - if ($ffprobe_out['format']['format_name'] != 'matroska,webm') - return array('error' => array('code' => 2, 'msg' => $config['error']['invalidwebm']."error 1")); + if ($ffprobe_out['format']['format_name'] != 'matroska,webm') { + return [ + 'error' => [ + 'code' => 2, + 'msg' => $config['error']['invalidwebm'] . 'error 1' + ] + ]; + } } elseif ($extension === 'mp4' || stristr($ffprobe_out['format']['format_name'], 'mp4')) { - // if the video is not h264 or (there is audio but it's not aac) - if (($ffprobe_out['streams'][$videoidx]['codec_name'] != 'h264') || ((count($trackmap['audioat']) > 0) && ($ffprobe_out['streams'][$trackmap['audioat'][0]]['codec_name'] != 'aac'))) - return array('error' => array('code' => 2, 'msg' => $config['error']['invalidwebm']." [h264/aac check]")); + // If the video is not h264 or (there is audio but it's not aac). + if (($ffprobe_out['streams'][$videoidx]['codec_name'] != 'h264') || ((count($trackmap['audioat']) > 0) && ($ffprobe_out['streams'][$trackmap['audioat'][0]]['codec_name'] != 'aac'))) { + return [ + 'error' => [ + 'code' => 2, + 'msg' => $config['error']['invalidwebm'] . ' [h264/aac check]' + ] + ]; + } } else { - return array('error' => array('code' => 1, 'msg' => $config['error']['genwebmerror']."error 3")); + return [ + 'error' => [ + 'code' => 1, + 'msg' => $config['error']['genwebmerror'] . 'error 3' + ] + ]; + } + if ((count($ffprobe_out['streams']) > 1) && (!$config['webm']['allow_audio'])) { + return [ + 'error' => [ + 'code' => 3, + 'msg' => $config['error']['webmhasaudio'] . 'error 4' + ] + ]; } - if ((count($ffprobe_out['streams']) > 1) && (!$config['webm']['allow_audio'])) - return array('error' => array('code' => 3, 'msg' => $config['error']['webmhasaudio']."error 4")); if ((count($trackmap['audioat']) > 0) && !$config['webm']['allow_audio']) { - return array('error' => array('code' => 3, 'msg' => $config['error']['webmhasaudio']."error 5")); + return [ + 'error' => [ + 'code' => 3, + 'msg' => $config['error']['webmhasaudio'] . 'error 5' + ] + ]; } - if ($ffprobe_out['format']['duration'] > $config['webm']['max_length']) - return array('error' => array('code' => 4, 'msg' => sprintf($config['error']['webmtoolong'], $config['webm']['max_length'])."error 6")); - return array('error' => array(), 'trackmap' => $trackmap); + if ($ffprobe_out['format']['duration'] > $config['webm']['max_length']) { + return [ + 'error' => [ + 'code' => 4, + 'msg' => sprintf($config['error']['webmtoolong'], $config['webm']['max_length']) . 'error 6' + ] + ]; + } + return [ + 'error' => [], + 'trackmap' => $trackmap + ]; } + function make_webm_thumbnail($filename, $thumbnail, $width, $height, $duration) { - global $board, $config; + global $config; + $filename = escapeshellarg($filename); - $thumbnailfc = escapeshellarg($thumbnail); // Should be safe by default but you - // can never be too safe. + // Should be safe by default but you can never be too safe. + $thumbnailfc = escapeshellarg($thumbnail); + + // Same as above. $width = escapeshellarg($width); - $height = escapeshellarg($height); // Same as above. + $height = escapeshellarg($height); $ffmpeg = $config['webm']['ffmpeg_path']; $ret = 0; - $ffmpeg_out = array(); + $ffmpeg_out = []; + exec("$ffmpeg -strict -2 -ss " . floor($duration / 2) . " -i $filename -v quiet -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnailfc 2>&1", $ffmpeg_out, $ret); - // Work around for https://trac.ffmpeg.org/ticket/4362 + + // Work around for https://trac.ffmpeg.org/ticket/4362. if (filesize($thumbnail) === 0) { - // try again with first frame + // Try again with first frame. exec("$ffmpeg -y -strict -2 -ss 0 -i $filename -v quiet -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnailfc 2>&1", $ffmpeg_out, $ret); clearstatcache(); - // failed if no thumbnail size even if ret code 0, ffmpeg is buggy + // Failed if no thumbnail size even if ret code 0, ffmpeg is buggy. if (filesize($thumbnail) === 0) { $ret = 1; }