Skip to content

Commit a357d09

Browse files
committed
Fix seek and trim issues
1 parent d50c006 commit a357d09

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

demo/src/main/java/com/otaliastudios/transcoder/demo/TranscoderActivity.java

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.util.ArrayList;
3939
import java.util.List;
4040
import java.util.concurrent.Future;
41-
import java.util.function.Consumer;
4241

4342
import androidx.annotation.NonNull;
4443
import androidx.appcompat.app.AppCompatActivity;

lib/src/main/java/com/otaliastudios/transcoder/internal/Segments.kt

+12
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ internal class Segments(
6868
log.i("tryCreateSegment($type, $index): created!")
6969
if (tracks.active.has(type)) {
7070
source.selectTrack(type)
71+
// TODO this sucks
72+
// By design, all sources must select all tracks before seeking. We can achieve this
73+
// here but it still doesn't look right. The other source might be on a different
74+
// point in the timeline, or it might be hidden because wrapped in a DataSourceWrapper...
75+
// We have no checks for any of these options and they can all break concatenation.
76+
val other = when (type) {
77+
TrackType.AUDIO -> TrackType.VIDEO
78+
TrackType.VIDEO -> TrackType.AUDIO
79+
}
80+
if (tracks.active.has(other) && sources[other].any { it === source }) {
81+
source.selectTrack(other)
82+
}
7183
}
7284
// Update current index before pipeline creation, for other components
7385
// who check it during pipeline init.

lib/src/main/java/com/otaliastudios/transcoder/source/DefaultDataSource.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,19 @@ public boolean isInitialized() {
120120
@Override
121121
public void selectTrack(@NonNull TrackType type) {
122122
LOG.i("selectTrack(" + type + ")");
123-
mSelectedTracks.add(type);
124-
mExtractor.selectTrack(mIndex.get(type));
123+
if (!mSelectedTracks.contains(type)) {
124+
mSelectedTracks.add(type);
125+
mExtractor.selectTrack(mIndex.get(type));
126+
}
125127
}
126128

127129
@Override
128130
public void releaseTrack(@NonNull TrackType type) {
129131
LOG.i("releaseTrack(" + type + ")");
130-
mSelectedTracks.remove(type);
131-
mExtractor.unselectTrack(mIndex.get(type));
132+
if (mSelectedTracks.contains(type)) {
133+
mSelectedTracks.remove(type);
134+
mExtractor.unselectTrack(mIndex.get(type));
135+
}
132136
}
133137

134138
protected abstract void initializeExtractor(@NonNull MediaExtractor extractor) throws IOException;

lib/src/main/java/com/otaliastudios/transcoder/source/TrimDataSource.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,29 @@ public void initialize() {
5858
throw new IllegalArgumentException(
5959
"Trim values cannot be greater than media duration.");
6060
}
61+
LOG.i("initialize(): duration=" + duration
62+
+ " trimStart=" + trimStartUs
63+
+ " trimEnd=" + trimEndUs
64+
+ " trimDuration=" + (duration - trimStartUs - trimEndUs));
6165
trimDurationUs = duration - trimStartUs - trimEndUs;
6266
}
6367

68+
// Assuming e.g. video of 8 seconds, trimStart=2s, trimEnd=1s.
69+
// The trimmed duration is 5 seconds. Assume also that the video has sparse keyframes
70+
// so that when we do seekTo(2s), it returns 0 because it couldn't seek there. We have two options:
71+
// - duration=5s, position goes from -2s to 5s
72+
// - duration=7s, position goes from 0s to 7s
73+
// What we choose is not so important, as long as we use the same approach in getDurationUs
74+
// and getPositionUs consistently. Approach 1 would be easier (no extra) but also weird.
75+
6476
@Override
6577
public long getDurationUs() {
6678
return trimDurationUs + extraDurationUs;
6779
}
6880

6981
@Override
7082
public long getPositionUs() {
71-
return super.getPositionUs() - trimStartUs;
83+
return super.getPositionUs() - trimStartUs + extraDurationUs;
7284
}
7385

7486
@Override
@@ -77,6 +89,9 @@ public boolean canReadTrack(@NonNull TrackType type) {
7789
// tracks have been selected.
7890
if (!trimDone && trimStartUs > 0) {
7991
extraDurationUs = trimStartUs - getSource().seekTo(trimStartUs);
92+
LOG.i("canReadTrack(): extraDurationUs=" + extraDurationUs
93+
+ " trimStartUs=" + trimStartUs
94+
+ " source.seekTo(trimStartUs)=" + (extraDurationUs - trimStartUs));
8095
trimDone = true;
8196
}
8297
return super.canReadTrack(type);

0 commit comments

Comments
 (0)