Skip to content

Commit e89e685

Browse files
authored
Merge pull request #833 from jgraef/fix-symphonia-current-span-length
fix: `SymphoniaDecoder::current_span_length` now returns `None` instead of `Some(0)`
2 parents e007071 + 51acc39 commit e89e685

1 file changed

Lines changed: 22 additions & 15 deletions

File tree

src/decoder/symphonia.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(crate) struct SymphoniaDecoder {
2828
buffer: SampleBuffer<Sample>,
2929
spec: SignalSpec,
3030
seek_mode: SeekMode,
31+
selected_track_id: u32,
3132
}
3233

3334
impl SymphoniaDecoder {
@@ -82,25 +83,15 @@ impl SymphoniaDecoder {
8283
};
8384

8485
// Select the first supported track
85-
let track_id = probed
86+
let track = probed
8687
.format
8788
.tracks()
8889
.iter()
8990
.find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
9091
.ok_or(symphonia::core::errors::Error::Unsupported(
9192
"No track with supported codec",
92-
))?
93-
.id;
94-
95-
let track = match probed
96-
.format
97-
.tracks()
98-
.iter()
99-
.find(|track| track.id == track_id)
100-
{
101-
Some(track) => track,
102-
None => return Ok(None),
103-
};
93+
))?;
94+
let track_id = track.id;
10495

10596
let mut decoder = symphonia::default::get_codecs()
10697
.make(&track.codec_params, &DecoderOptions::default())?;
@@ -123,8 +114,8 @@ impl SymphoniaDecoder {
123114
continue;
124115
}
125116

126-
match decoder.decode(&current_span) {
127-
Ok(decoded) => break decoded,
117+
let decoded = match decoder.decode(&current_span) {
118+
Ok(decoded) => decoded,
128119
Err(e) => match e {
129120
Error::DecodeError(_) => {
130121
// Decode errors are intentionally ignored with no retry limit.
@@ -134,6 +125,15 @@ impl SymphoniaDecoder {
134125
}
135126
_ => return Err(e),
136127
},
128+
};
129+
130+
// Loop until we get a packet with audio frames. This is necessary because some
131+
// formats can have packets with only metadata, particularly when rewinding, in
132+
// which case the iterator would otherwise end with `None`.
133+
// Note: checking `decoded.frames()` is more reliable than `packet.dur()`, which
134+
// can resturn non-zero durations for packets without audio frames.
135+
if decoded.frames() > 0 {
136+
break decoded;
137137
}
138138
};
139139
let spec = decoded.spec().to_owned();
@@ -146,6 +146,7 @@ impl SymphoniaDecoder {
146146
buffer,
147147
spec,
148148
seek_mode,
149+
selected_track_id: track_id,
149150
}))
150151
}
151152

@@ -301,6 +302,12 @@ impl Iterator for SymphoniaDecoder {
301302
if self.current_span_offset >= self.buffer.len() {
302303
let decoded = loop {
303304
let packet = self.format.next_packet().ok()?;
305+
306+
// If the packet does not belong to the selected track, skip over it
307+
if packet.track_id() != self.selected_track_id {
308+
continue;
309+
}
310+
304311
let decoded = match self.decoder.decode(&packet) {
305312
Ok(decoded) => decoded,
306313
Err(Error::DecodeError(_)) => {

0 commit comments

Comments
 (0)