ffmpeg.php: improve multitrack support

This commit is contained in:
Zankaria 2025-10-09 23:19:03 +02:00
parent 1a803170ca
commit cc084a3444

View file

@ -18,7 +18,7 @@ function get_webm_info($filename) {
$webminfo['error'] = $validcheck['error']; $webminfo['error'] = $validcheck['error'];
if (empty($webminfo['error'])) { if (empty($webminfo['error'])) {
$trackmap = $validcheck['trackmap']; $trackmap = $validcheck['trackmap'];
$videoidx = $trackmap['videoat'][0]; $videoidx = $trackmap['videoat'][$validcheck['video_idx']];
$webminfo['width'] = $ffprobe_out['streams'][$videoidx]['width']; $webminfo['width'] = $ffprobe_out['streams'][$videoidx]['width'];
$webminfo['height'] = $ffprobe_out['streams'][$videoidx]['height']; $webminfo['height'] = $ffprobe_out['streams'][$videoidx]['height'];
$webminfo['duration'] = $ffprobe_out['format']['duration']; $webminfo['duration'] = $ffprobe_out['format']['duration'];
@ -53,7 +53,15 @@ function locate_webm_tracks($ffprobe_out) {
return [ 'videoat' => $video_at, 'audioat' => $audio_at ]; return [ 'videoat' => $video_at, 'audioat' => $audio_at ];
} }
function is_valid_webm($ffprobe_out) { /**
* @param string $ffprobe_out
* @return array<array> An array with the following values:
* error: array with error code and message
* trackmap: decoded ffprobe output
* video_idx: int, index of the video track
* audio_idx: ?int, index of the audio track, if present
*/
function is_valid_webm(array $ffprobe_out) {
global $config; global $config;
if (empty($ffprobe_out)) { if (empty($ffprobe_out)) {
@ -78,7 +86,6 @@ function is_valid_webm($ffprobe_out) {
$trackmap = locate_webm_tracks($ffprobe_out); $trackmap = locate_webm_tracks($ffprobe_out);
// one video track
if (count($trackmap['videoat']) < 1) { if (count($trackmap['videoat']) < 1) {
return [ return [
'error' => [ 'error' => [
@ -87,8 +94,18 @@ function is_valid_webm($ffprobe_out) {
] ]
]; ];
} }
// If there's more than one video, yolo it if (count($trackmap['audioat']) != 0 && !$config['webm']['allow_audio']) {
$videoidx = $trackmap['videoat'][0]; return [
'error' => [
'code' => 3,
'msg' => $config['error']['webmhasaudio'] . 'error 5'
]
];
}
$audio_idx = count($trackmap['audioat']) > 0 ? 0 : null;
$video_idx = 0;
$extension = \pathinfo($ffprobe_out['format']['filename'], \PATHINFO_EXTENSION); $extension = \pathinfo($ffprobe_out['format']['filename'], \PATHINFO_EXTENSION);
if ($extension === 'webm' && !stristr($ffprobe_out['format']['format_name'], 'mp4')) { if ($extension === 'webm' && !stristr($ffprobe_out['format']['format_name'], 'mp4')) {
@ -101,8 +118,28 @@ function is_valid_webm($ffprobe_out) {
]; ];
} }
} elseif ($extension === 'mp4' || stristr($ffprobe_out['format']['format_name'], 'mp4')) { } elseif ($extension === 'mp4' || stristr($ffprobe_out['format']['format_name'], 'mp4')) {
$any_h264 = false;
for ($i = 0; $i < count($trackmap['videoat']); $i++) {
if ($ffprobe_out['streams'][$i]['codec_name'] == 'h264') {
$video_idx = $i;
$any_h264 = true;
break;
}
}
$any_aac = false;
if ($audio_idx !== null) {
for ($i = 0; $i < count($trackmap['audioat']); $i++) {
if ($ffprobe_out['streams'][$i]['codec_name'] == 'h264') {
$audio_idx = $i;
$any_aac = true;
break;
}
}
}
// If the video is not h264 or (there is audio but it's not aac). // 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'))) { if (!$any_h264 || ($audio_idx !== null && !$any_aac)) {
return [ return [
'error' => [ 'error' => [
'code' => 2, 'code' => 2,
@ -118,18 +155,12 @@ function is_valid_webm($ffprobe_out) {
] ]
]; ];
} }
if ((count($trackmap['audioat']) > 0) && !$config['webm']['allow_audio']) {
return [
'error' => [
'code' => 3,
'msg' => $config['error']['webmhasaudio'] . 'error 5'
]
];
}
return [ return [
'error' => [], 'error' => [],
'trackmap' => $trackmap 'trackmap' => $trackmap,
'video_idx' => $video_idx,
'audio_idx' => $audio_idx
]; ];
} }