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

[Feature Request] Trim time #37

Closed
aweck opened this issue Oct 17, 2019 · 3 comments
Closed

[Feature Request] Trim time #37

aweck opened this issue Oct 17, 2019 · 3 comments

Comments

@aweck
Copy link
Contributor

aweck commented Oct 17, 2019

Is there a good way to trim the time of a video while transcoding? Similar to this: ypresto/android-transcoder#14

@natario1
Copy link
Member

It's not supported at the moment, sorry! If you want to implement on your own, I would use a custom DataSource subclass.

@aweck
Copy link
Contributor Author

aweck commented Oct 17, 2019

@natario1 Thanks! Would you be open to a pull request adding this feature? It's required for my use case, but I'd prefer if I could check it in here as having a custom lib would make maintenance and updates more painful.

@natario1
Copy link
Member

natario1 commented Oct 17, 2019

Sure! I can give you advices if you need.

The key part that is important to me, is that we should implement this as an isolated component, like a TrimDataSource class, without touching the other components in the pipeline.

This way the usage would be:

// Wrap source
DataSource source = ...;
DataSource wrapper = new TrimDataSource(source, trimStart, trimEnd);

// Then pass to transcoder as a regular source
Transcoder.into(file)
    .addSource(wrapper)
    .transcode()

And you could trim separately each segment in case of concatenation.

mudar added a commit to mudar/Transcoder that referenced this issue Dec 20, 2019
- New component TrimDataSource, wrapping DataSource to be trimmed.
- MediaExtractorDataSource is an abstract class to limit visibility of
MediaExtractor to package
- Updates to Engine to replace
selectAudio/transcode/selectVideo/transcode sequence by
selectAudio/selectVideo/transcode/transcode
@mudar mudar mentioned this issue Dec 20, 2019
natario1 pushed a commit that referenced this issue Jan 7, 2020
* Add support for trim, related to issue #37

- New component TrimDataSource, wrapping DataSource to be trimmed.
- MediaExtractorDataSource is an abstract class to limit visibility of
MediaExtractor to package
- Updates to Engine to replace
selectAudio/transcode/selectVideo/transcode sequence by
selectAudio/selectVideo/transcode/transcode

* Added support for TrimDataSource into demo app

Using 2 editText fields, default value is zero.

* TranscoderOptions Builder support for TrimDataSource

Builder can add directly trim values for UriDataSource

* TrimDataSource updates following PR code review

- fixed case where video track is absent
- throw exceptions for invalid trim values

* Removed unnecessary changes to Engine

In the original sequence
selectAudio / transcodeAudio / selectVideo / transcodeVideo
the first step (selectAudio) is intercepted by selectVideo + seekVideo
and the 3rd step (selectVideo) is skipped. So it becomes
selectVideo / seekVideo / selectAudio / transcodeAudio / transcodeVideo
- Also added throws IllegalArgumentException to TrimDataSource

* Moved seekTo() from selectTrack() to canReadTrack()

Cleaner simplified code :)
The extractor needs a second call to seekTo() after reaching a video
keyframe, to obtain better values for audio track. Otherwise, too many
audio frames can be lost, causing visible off-sync.

* Removed MediaExtractorDataSource

Replaced by adding seekTo() to DataSource interface

* Removed timestamp adjustment

The rest of the lib already assumes that timestamps start from arbitrary
values.

* Use TrackTypeMap for readyTracks flags

replacing two booleans

* Handle trimEnd in isDrained()

Stop reading when readUs is past duration. This removes the need to
manually define KEY_DURATION in the mediaFormat

* Fix seek vs canRead order

to avoid possible bug where seekTo lands on a different track. Ex: The
upstream source might be on AUDIO position, but if you seek later, the
next position might VIDEO instead.

* Apply seekTo() once per selected track

- Updates to Engine to replace
selectAudio/transcode/selectVideo/transcode sequence by
selectAudio/selectVideo/transcode/transcode
- remove unnecessary hasTrack()
- seekTo() is applied in canReadTrack(), once per selected track. This
now works because all track selection operations are done before the
first call to canReadTrack().
- When 2 tracks are selected, seekTo() is called twice and this helps
the extractor with Audio sampleTime issues.

* seekBy() replaces seekTo(), selecting all tracks

- reverted unnecessary changes to Engine class. Previous changes cannot
guarantee that all calls to selectTracks() are done before the first
canRead(). Latest bug was with merging multiple trimmed files.
- use seekBy() to better handle first extractor timestamp
- DefaultDataSource makes sure all available tracks are selected by
extractor (without adding to mSelectedTracks array). Then seekTo() is
called mutlitple times, using the resulting sampletimeUs for the later
calls.
@natario1 natario1 closed this as completed Jan 9, 2020
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