Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebM generates an empty video file, H264 works as expected. #72

Open
benfeather opened this issue Feb 26, 2024 · 11 comments
Open

WebM generates an empty video file, H264 works as expected. #72

benfeather opened this issue Feb 26, 2024 · 11 comments
Labels

Comments

@benfeather
Copy link

Describe the bug

I'm using the transcoder plugin inside of a custom Craft module.

The plugin produces an empty video file when I transcode a video using the default WebM config.
However, if I use the default h264 config, the plugin works as expected.

Here is a cut-down version of the module:

public function actionIndex()
{
	$id = Craft::$app->request->get('id');

	if (!$id) {
		throw new \Exception('ID parameter is required.');
	}

	$asset = Asset::find()->id($id)->one();

	if (!$asset) {
		throw new \Exception("Asset matching ID '{$id}' not found.");
	}

	$transcoder = Craft::$app->plugins->getPlugin('transcoder');

	if (!$transcoder || !($transcoder instanceof Transcoder)) {
		throw new \Exception('Transcoder plugin not found.');
	}

	$url = $transcoder->transcode->getVideoUrl($asset, [
		'videoEncoder' => 'webm',
	]);

	return $this->asJson([
		'src' => $url,
	]);
}

If I manually run FFMPEG inside the ddev container, the video is transcoded to WebM as expected, so I don't believe FFMPEG is the issue.

Expected behaviour

A WebM version of the video asset is to be generated.

Versions

  • DDEV version: 1.22.7
  • PHP: 8.2.15
  • Plugin version: 4.0.1
  • Craft version: 4.7.4
  • FFMPEG version: 4.3.6
@benfeather benfeather added the bug label Feb 26, 2024
@khalwat
Copy link
Contributor

khalwat commented Feb 26, 2024

Show me the command line you used that did generate a .webm properly for you on your setup?

@benfeather
Copy link
Author

Here's the command: ffmpeg -i Input.mp4 -c:v libvpx -c:a libvorbis -quality good -cpu-used 0 Output.webm

@khalwat
Copy link
Contributor

khalwat commented Feb 26, 2024

And what is the command that Transcoder is outputting when you try to use it? It should be in your config/logs/web.log assuming devMode is on.

@benfeather
Copy link
Author

Here's the command that gets logged:

/usr/bin/ffmpeg -i '/var/www/html/web/uploads/videos/Racewell-Sheep-Handler/Dagging.mp4' -vcodec libvpx -quality good -cpu-used 0 -bufsize 1000k -threads 0 -vf "scale=300:240,unsharp=5:5:1.0:5:5:0.0" -c:a copy -f webm -y '/var/www/html/web/transcoder/video/Racewell-Sheep-Handler/Dagging_300w_240h.webm'

If I run that command, I get this error:

"Rate control parameters set without a bitrate. Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height"

I haven't modified the transcoder.php config file, so it should use the default values.

@khalwat
Copy link
Contributor

khalwat commented Feb 26, 2024

The default parameters that are in Transcoder definitely worked at one point for webm -- my guess is that something (whether ffmpeg itself, or the libvpx codex) changed in the interim.

The major different I can see between the command that worked, and the one that did not is the audio codec setting: -c:a copy is used as a default in Transcoder, and your example is explicitly using -c:a libvorbis

@benfeather
Copy link
Author

benfeather commented Feb 26, 2024

If you remove -bufsize 1000k, the command throws a different error:

Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM. Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument Error initializing output stream 0:0 --

If you swap -c:a copy with -c:a libvorbis or -c:a libopus the conversion succeeds.

/usr/bin/ffmpeg \
	-i '/var/www/html/web/uploads/videos/Racewell-Sheep-Handler/Dagging.mp4' \
	-c:v libvpx \
	-c:a libvorbis \
	-quality good \
	-cpu-used 0 \
	-threads 0 \
	-vf "scale=300:240,unsharp=5:5:1.0:5:5:0.0" \
	-f webm \
	-y \
	'/var/www/html/web/transcoder/video/Racewell-Sheep-Handler/Dagging_300w_240h.webm'

@benfeather
Copy link
Author

I tried the command with -bufsize 1000k and -b:v 2M, and it worked. Looks like you have to set the target average bitrate for the bufsize flag to work.

I don't know what a reasonable default would be.

https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate

@khalwat
Copy link
Contributor

khalwat commented Feb 26, 2024

Maybe best to just remove the -bufsize flag entirely then, and let ffmpeg figure it out.

My guess is the reason why copy doesn't work is the encoding on the audio track is such that isn't supported in webm somehow.

In any event, glad you got it working!

@khalwat khalwat closed this as completed Feb 26, 2024
@benfeather
Copy link
Author

It looks like the -bufsize flag is hardcoded into the FFmpeg command:

Transcode.php, line 131
CleanShot 2024-02-27 at 09 09 36@2x

Is that something you could remove? Or is there a way I can override it?

@jowhannez
Copy link

I am also getting an empty webm when specifying "videoEncoder": "webm", I'm assuming it's the same issue since the hardcoded flag is still present in Transcode.php?

@khalwat
Copy link
Contributor

khalwat commented Nov 4, 2024

Yeah I think the best course of action is just to remove that flag.

@khalwat khalwat reopened this Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants