phpvideotoolkit-v2 icon indicating copy to clipboard operation
phpvideotoolkit-v2 copied to clipboard

Aspect ratio for extracted frame

Open sapzxc opened this issue 11 years ago • 23 comments

Help me guys with this: I test video 640x480.

Its normal video, without rotation. Extracted frame looks like: 0324864_05

Then I rotate video and then extract same frame: 0324866_05

There aspect ratio trouble. When I manually set aspect ratio - it looks good. First minds is extracting video dimensions and put aspect ration to "extract frame" code. Is it good idea or exists another workaround?

sapzxc avatar Apr 08 '14 15:04 sapzxc

Hi there. Can you attach the code you are using please?

buggedcom avatar Apr 08 '14 16:04 buggedcom

or at least capture and output the commands being sent to ffmpeg

buggedcom avatar Apr 08 '14 16:04 buggedcom

See my gist https://gist.github.com/sapzxc/10171091

download it, then run test.sh It creates 1.mp4 1.jpg - normal, 2.mp4 2.jpg - rotated video and frame.

sapzxc avatar Apr 08 '14 19:04 sapzxc

Thanks. I'm looking into it now. As i see it the problem can be described as:

1.mp4 - ok 1.jpg - ok 2.mp4 - ok 2.jpg - error

I'm just adding the raw commands below for future reference:

/opt/local/bin/ffmpeg '-i' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/1.mov' '-y' '-qscale' '4' '-f' 'mp4' '-strict' 'experimental' '-threads' '1' '-acodec' 'aac' '-ab' '96k' '-ar' '48000' '-ac' '2' '-vcodec' 'h264' '-s' '640x480' '-b:v' '2500k' '-profile:v' 'main' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/1.mp4'
/opt/local/bin/ffmpeg '-i' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/1.mp4' '-y' '-ss' '00:00:12.00' '-qscale' '4' '-f' 'image2' '-strict' 'experimental' '-threads' '1' '-an' '-vcodec' 'mjpeg' '-r' '1' '-vframes' '1' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/1.jpg'
/opt/local/bin/ffmpeg '-i' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/1.mov' '-y' '-qscale' '4' '-f' 'mp4' '-strict' 'experimental' '-threads' '1' '-acodec' 'aac' '-ab' '96k' '-ar' '48000' '-ac' '2' '-vcodec' 'h264' '-s' '640x480' '-b:v' '2500k' '-vf' 'transpose=1' '-profile:v' 'main' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/2.mp4'
/opt/local/bin/ffmpeg '-i' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/2.mp4' '-y' '-ss' '00:00:12.00' '-qscale' '4' '-f' 'image2' '-strict' 'experimental' '-threads' '1' '-an' '-vcodec' 'mjpeg' '-r' '1' '-vframes' '1' '/Users/ollie/Downloads/gist10171091-ac8a4c4061036610fea01e0aed53fea39d8b9835/2.jpg'

buggedcom avatar Apr 08 '14 19:04 buggedcom

Looking at the command strings, it would appear as if you have possibly found an issue with ffmpeg. Although I'm not 100% sure. The command strings look as if they should generate the correct thumbnails.

buggedcom avatar Apr 08 '14 19:04 buggedcom

Hmmm. It seems that ffmpeg doesn't re-encode the correct video dimensions once rotated, although it does store the aspect ratio correctly.

This is the output from $video->read() when inspecting 2.mp4

    [video] => Array
        (
            [stream] => 0:0
            [dimensions] => Array
                (
                    [width] => 640
                    [height] => 480
                )

            [bitrate] => 664000
            [time_bases] => Array
                (
                    [fps] => 10
                    [tbr] => 10
                    [tbn] => 10240
                    [tbc] => 20
                )

            [frames] => Array
                (
                    [total] => 250
                    [rate] => 10
                    [avg_rate] => 
                )

            [pixel_aspect_ratio] => 9:16
            [display_aspect_ratio] => 3:4
            [rotation] => 
            [pixel_format] => yuv420p
            [language] => eng
            [codec] => Array
                (
                    [name] => h264
                    [profile] => Main
                    [tag_string] => 0x31637661
                    [tag] => avc1
                    [raw] => h264 (Main) (avc1 / 0x31637661)
                )

            [metadata] => Array
                (
                    [handler_name] => VideoHandler
                )

        )

You can see that the width and height are not correct, however the aspect ratio is. A bit annoying, but I'm sure I can add some additional checks to make sure the width and height obey aspect ratio.

buggedcom avatar Apr 08 '14 19:04 buggedcom

Interestingly if you re-encode 2.mp4 using fetch.php to just be 2a.mp4 the aspect ratio is also borked.

buggedcom avatar Apr 08 '14 19:04 buggedcom

As I understand we must setup aspect ratio with transcode operation.

Similar issues (search on page by "aspect" keyword): https://github.com/rheaton/carrierwave-video/issues/21 http://superuser.com/questions/630433/rotate-a-video-90-degrees http://stackoverflow.com/questions/21709900/ffmpeg-conditional-rotation-of-video

sapzxc avatar Apr 08 '14 19:04 sapzxc

created an automatic patch so that PHPVideoToolkit detects this silliness and automatically applies dimension commands when needed. It is in the head of master. I will create a tag shortly. Thanks for finding the bug.

buggedcom avatar Apr 08 '14 19:04 buggedcom

fixed in fb302e32d4eae6c654524d8c39779e123fe1c3a6

buggedcom avatar Apr 08 '14 20:04 buggedcom

Related tag: https://github.com/buggedcom/phpvideotoolkit-v2/releases/tag/2.1.6-beta

buggedcom avatar Apr 08 '14 20:04 buggedcom

argh. Just read your links. Seems whilst this fix does actually work, the links suggest a better alternative.

buggedcom avatar Apr 08 '14 20:04 buggedcom

Whilst this patch will do what you want, and I will create a further patch, you xould in the mean time just call $video->setVideoAspectRatio() yourself?

buggedcom avatar Apr 08 '14 20:04 buggedcom

Something wrong: I added $outputFormat->setVideoAspectRatio('3:4');

Got:

CommandString: /usr/bin//ffmpeg '-i' '/usr/www/fmqa/public/test/1.mov' '-y' '-qscale' '4' '-f' 'mp4' '-strict' 'experimental' '-threads' '1' '-acodec' 'aac' '-ab' '96k' '-ar' '48000' '-ac' '2' '-vcodec' 'h264' '-s' '540x405' '-aspect' '3:4' '-b:v' '2500k' '-vf' 'transpose=1' '-profile:v' 'main' '/usr/www/fmqa/public/test/2.mp4'

Actual error: height not divisible by 2 (540x405) Its because: yuv420p

But why it made dimensions 540x405 from 640x480?

sapzxc avatar Apr 08 '14 20:04 sapzxc

It could be there is a bug in the aspect ratio setting. By default it should not automatically adjust the width and height to fit the new ratio, however I guess there might be a bug somewhere if it is resizing it unexpectedly. will look into that too.

buggedcom avatar Apr 08 '14 20:04 buggedcom

bugs fixed and methods updated in master. Please let me know if it works for you now.

buggedcom avatar Apr 08 '14 20:04 buggedcom

Now my test works and image has proper aspect. But strange dimensions still there. 1.mp4: '-s' '640x480' - good 2.mp4: '-s' '360x270' '-aspect' '3:4' - wrong? It should be 640x480 or 480x640, but why 360x270?

ffprobe of 1.mp4 and 2.mp4: Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 640x480 [SAR 1:1 DAR 4:3], Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 360x270 [SAR 9:16 DAR 3:4]

Now investigating...

sapzxc avatar Apr 08 '14 21:04 sapzxc

It's todo with Video::setVideoDimensions

setVideoDimensions($width, $height=null, $auto_adjust_dimensions_to_optimal=false, $force_aspect_ratio=false)

In the previous version the $auto_adjust_dimensions_to_optimal placeholder was defaulting to true. Can you check that file to see if it's updated for you?

buggedcom avatar Apr 08 '14 21:04 buggedcom

Updated scripts and it works! But have another issue with size, You hate me I know =)

Source file is 640x480. First not rotated file has size 1280x720 Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 3:4 DAR 4:3]

And rotated 360x480 Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 360x480 [SAR 1:1 DAR 3:4]

Looks like need setup source size everywhere or destination size everywhere. I think it should be source size if it smaller than destination. It should not scale video in to bigger size.

sapzxc avatar Apr 08 '14 21:04 sapzxc

No worries, glad to help, but I'm not entirely sure of what you mean?

buggedcom avatar Apr 08 '14 21:04 buggedcom

Oh, I understand, my last comment is wrong. I was playing with code and there was error. Now works, I got one file 1024x768 and second 540x720. Good.

But if I want preserve source dimensions I write: ->setVideoDimensions(\PHPVideoToolkit\VideoFormat::DIMENSION_HD720,null,true) Then I got normal first file without rotation. ok. But when I try rotate I got error related to pixel aspect ratio, because size now 540x405.

I investigated, its because getOptimalDimensions called with 540, 720 params as target size and then function trimmed height to 405. But why it calculate in this way? If I have 640x480 - I must get optimal size 360x480 - it is actual optimal size. Why used that algorithm?

sapzxc avatar Apr 08 '14 22:04 sapzxc

Did you manage to sort this out? Was there an error in the algorithm? It looks as if the wrong dimension is being used to calculate the optimum size.

buggedcom avatar Jun 04 '14 20:06 buggedcom

Sorry for the delay of my response. I have created fork for last version on 2014-06-18 and added here tests based on phpunit. Using tests we can define default behavior of the framework. You also consider?

Now I bumped of this issue: When I convert smaller video to HD - I got bigger video. So I use param $auto_adjust_dimensions_to_optimal , but when I set it to true - I got error "Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height".

Also I writed test for function getOptimalDimensions and it also working not as I expected.

I can manage with this after month (as I expecting). My project will be in tests and bugfixes stage, so I will check and fix all.

sapzxc avatar Jun 18 '14 17:06 sapzxc