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

Single frame movie fails due to lastEncodedDuration not having a value #22

Open
RJFMedia opened this issue Dec 5, 2018 · 4 comments
Open

Comments

@RJFMedia
Copy link

RJFMedia commented Dec 5, 2018

If you try to encode a movie with just one frame it fails due to lastEncodedDuration not having a meaningful value. I propose that if there’s only one buffer when the writer is marked as finished, 1 unit of the buffer’s time scale is used as the duration. I’ve implimented this in my own private fork but hasn’t been rigorously tested yet outside my use case.

@mrRay
Copy link
Contributor

mrRay commented Dec 5, 2018

thanks for the report- good catch!

if we automatically set the duration of the frame to (1/timescale) the frame duration may not be what you expect, because it's relatively common to use larger timescales to simplify the process of expressing frame times as the quotient of two integers. for example, a timescale of 600 can describe frame times for 15, 20, 24, 25, and 30 fps timelines- this may not be an issue if you're creating the timestamps yourself, but if you're working with frames from another source you'll encounter this sooner or later.

hmm...if the framework can't calculate the frame duration because there's only one frame, then we either have to make assumptions about the duration of the frame (not wild about this), or we have to rely on the dev to provide the correct frame duration somehow. i can add a simple setter that allows devs to provide a fallback framerate if you're encoding one-frame movies...how does that sound?

@RJFMedia
Copy link
Author

RJFMedia commented Dec 5, 2018

Good to know about timescale. A user settable fallback frame duration sounds great. Thanks!

@mrRay
Copy link
Contributor

mrRay commented Dec 6, 2018

commit d345920 introduces these changes. specifically:

  • adds the "AVFallbackFPSKey" to the options dict used to create an instance of AVAssetWriterHapInput. the value associated with this key is expected to be a number describing the expected fallback FPS of the movie you're encoding. this value is used to set the duration of the frame of single-frame movies (and only used for single-frame movies).
  • if the "AVFallbackFPSKey" is not present, the single frame of single-frame movies will have a duration of (1/timescale), which is exactly what you suggested

cheers
: : ray

@RJFMedia
Copy link
Author

RJFMedia commented May 6, 2019

This is the first time i've needed to do 29.97df, and since that is 1001/30000, the default 1/timescale trick doesn't work.

What I discovered is that on line 181 of AVAssetWriterHapInput, it checks for the existence of a dictionary for AVVideoCompressionPropertiesKey before looking for the AVFallbackFPSKey which shouldn't necessarily have to do with the compression settings. So it kept ignoring my fallback framerate since i hadn't specified a dict with quality, chunk settings. etc. In my fork i just removed that check and it was fine.

What I'm now finding though, is that the completed media is reporting a framerate of 30fps in media players and in the metadata, even though I've verified that throughout the encode process it was always reporting a duration of 1001/30000.

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

No branches or pull requests

2 participants