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

Audio with cover art should be opened as audio instead of video #687

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

vibhavsinha
Copy link

Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Fixed tickets fixes #323
Related issues/PRs #402 (comment)
License MIT

What's in this PR?

  • Edited the $ffmpeg->open() method to send Video if and only if at least one video stream is not marked as attatched_pic.
  • A sample audio file with cover which is created by adding a cover image to the already existing audio.mp3 using eye-d3
  • Functional tests to confirm the reported issue and verify the fix.

Why?

Fixes #323
FFMmpeg::open() has 'media type' bug with MP3s (image metadata)

Fffmpeg source uses this function to detect if a video stream is actually a valid video stream or just a cover art.
https://github.com/FFmpeg/FFmpeg/blob/release/4.2/libavformat/movenc.c#L149-L154

I did not use the patch in #402 (comment) because the codec_type can be either png or jpeg. If the codec_type is jpeg, that stream can be either a cover art or just a MotionJPEG video stream. Hence, it was not the right way to detect this.

BC Breaks/Deprecations

No.
There is a small chance that some code depends on this behavior to detect audio with cover images.

To Do

  • Create tests to confirm the issue
  • Fix till the new tests pass
  • Run full test suite after making the change

@jens1o
Copy link
Member

jens1o commented Feb 24, 2020

Thank you for preparing this fix. However, I still think this might be a breaking change. @alexander-schranz how would you like to proceed here? File a new major version or don't you think it is a breaking change?

foreach ($streams->videos() as $videoStream) {
$videoDisposition = $videoStream->get('disposition');
if ($videoDisposition['attached_pic'] !== 1) {
$hasVideo = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: You can add a break; after this to not iterate unnecessarily.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. done. vibhavsinha@7b57207

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a missing closing brace in this fix. It opens 3 and only closes 2

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code has been changed since the last comment here. I am sure it is balanced now. The reason for opening 3 and closing 2 is because the subtracted chunk also had one opening bracket. Hence, the added chunk should also have one extra opening brace.

$hasVideo = false;
foreach ($streams->videos() as $videoStream) {
$videoDisposition = $videoStream->get('disposition');
if ($videoDisposition['attached_pic'] !== 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this a little bit strange, should we not use instead a mime_type check on pathfile to check if its a video or audio file. I could think that there are videos without a attached_pic disposition so I would not depend on that.
Also it feels for me the false position to fix it as $streams->videos() should not return none video file atleast I would not expect that.

@romainneutron do you remember why this was done before over count($streams->videos()) instead of checking for mimetype?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is possible to reply for @romainneutron yet due to the current circumstances, I'd be happy to bring this a little bit forward. :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexander-schranz It is a valid idea to use the mime_type for identifying the audio and video formats. But I can guess why it might not have been chosen for this project.

There are way too many formats for audio and video both. And I am sure there are some which can be used to hold only one stream of either type. Keeping a list of mime types will limit us to a subset of formats supported, and it will be different from ffmpeg behavior.

AFAIK ffmpeg does not differentiate between audio and video files. It only uses the mime_type to parse the container structure. After parsing container, it works only with stream information.

@vibhavsinha
Copy link
Author

  • I have rebased this branch with the latest of master because there were way too many changes since then.
  • Thanks to the improved test cases, I also found a bug in my code when reading $videoStream->get('disposition'). It is fixed now. I have verified that test case passed in my fork.
  • Thanks for @fpolli for mentioning and reminding me of this PR. I do not do much PHP now, so had an opportunity to re-learn phpunit 😄. There was a question about mismatched braces that I did not understand. It somehow looked okay to me. Nonetheless, after the rebase and test cases, it should be fine.

@sgloe
Copy link

sgloe commented Jan 26, 2024

I would appreciate this fix as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FFMmpeg::open() has 'media type' bug with MP3s (image metadata)
5 participants