mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Update tokio and fix build
This commit is contained in:
parent
f037a42908
commit
47badd61e0
3 changed files with 149 additions and 13 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -1808,18 +1808,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.7"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
|
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "1.0.7"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
|
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2498,9 +2498,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.6.0"
|
version = "1.14.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd3076b5c8cc18138b8f8814895c11eb4de37114a5d127bafdc5e55798ceef37"
|
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2517,9 +2517,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "1.2.0"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37"
|
checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2539,9 +2539,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.6"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066"
|
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -2567,9 +2567,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.6.7"
|
version = "0.6.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
|
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
|
|
@ -23,7 +23,7 @@ futures-util = { version = "0.3", default_features = false, features = ["alloc"]
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
byteorder = "1.4"
|
byteorder = "1.4"
|
||||||
shell-words = "1.0.0"
|
shell-words = "1.0.0"
|
||||||
tokio = { version = "1", features = ["sync"] }
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "sync"] }
|
||||||
zerocopy = { version = "0.3" }
|
zerocopy = { version = "0.3" }
|
||||||
|
|
||||||
# Backends
|
# Backends
|
||||||
|
|
136
playback/src/decoder/symphonia_decoder.rs
Normal file
136
playback/src/decoder/symphonia_decoder.rs
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
use super::{AudioDecoder, AudioPacket, DecoderError, DecoderResult};
|
||||||
|
|
||||||
|
use crate::audio::AudioFile;
|
||||||
|
|
||||||
|
use symphonia::core::audio::{AudioBufferRef, Channels};
|
||||||
|
use symphonia::core::codecs::Decoder;
|
||||||
|
use symphonia::core::errors::Error as SymphoniaError;
|
||||||
|
use symphonia::core::formats::{FormatReader, SeekMode, SeekTo};
|
||||||
|
use symphonia::core::io::{MediaSource, MediaSourceStream};
|
||||||
|
use symphonia::core::units::TimeStamp;
|
||||||
|
use symphonia::default::{codecs::VorbisDecoder, formats::OggReader};
|
||||||
|
|
||||||
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
|
|
||||||
|
impl<R> MediaSource for FileWithConstSize<R>
|
||||||
|
where
|
||||||
|
R: Read + Seek + Send,
|
||||||
|
{
|
||||||
|
fn is_seekable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn byte_len(&self) -> Option<u64> {
|
||||||
|
Some(self.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FileWithConstSize<T> {
|
||||||
|
stream: T,
|
||||||
|
len: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FileWithConstSize<T> {
|
||||||
|
pub fn len(&self) -> u64 {
|
||||||
|
self.len
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> FileWithConstSize<T>
|
||||||
|
where
|
||||||
|
T: Seek,
|
||||||
|
{
|
||||||
|
pub fn new(mut stream: T) -> Self {
|
||||||
|
stream.seek(SeekFrom::End(0)).unwrap();
|
||||||
|
let len = stream.stream_position().unwrap();
|
||||||
|
stream.seek(SeekFrom::Start(0)).unwrap();
|
||||||
|
Self { stream, len }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Read for FileWithConstSize<T>
|
||||||
|
where
|
||||||
|
T: Read,
|
||||||
|
{
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
self.stream.read(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Seek for FileWithConstSize<T>
|
||||||
|
where
|
||||||
|
T: Seek,
|
||||||
|
{
|
||||||
|
fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> {
|
||||||
|
self.stream.seek(pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SymphoniaDecoder {
|
||||||
|
track_id: u32,
|
||||||
|
decoder: Box<dyn Decoder>,
|
||||||
|
format: Box<dyn FormatReader>,
|
||||||
|
position: TimeStamp,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymphoniaDecoder {
|
||||||
|
pub fn new<R>(input: R) -> DecoderResult<Self>
|
||||||
|
where
|
||||||
|
R: Read + Seek,
|
||||||
|
{
|
||||||
|
let mss_opts = Default::default();
|
||||||
|
let mss = MediaSourceStream::new(Box::new(FileWithConstSize::new(input)), mss_opts);
|
||||||
|
|
||||||
|
let format_opts = Default::default();
|
||||||
|
let format = OggReader::try_new(mss, &format_opts).map_err(|e| DecoderError::SymphoniaDecoder(e.to_string()))?;
|
||||||
|
|
||||||
|
let track = format.default_track().unwrap();
|
||||||
|
let decoder_opts = Default::default();
|
||||||
|
let decoder = VorbisDecoder::try_new(&track.codec_params, &decoder_opts)?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
track_id: track.id,
|
||||||
|
decoder: Box::new(decoder),
|
||||||
|
format: Box::new(format),
|
||||||
|
position: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AudioDecoder for SymphoniaDecoder {
|
||||||
|
fn seek(&mut self, absgp: u64) -> DecoderResult<()> {
|
||||||
|
let seeked_to = self.format.seek(
|
||||||
|
SeekMode::Accurate,
|
||||||
|
SeekTo::Time {
|
||||||
|
time: absgp, // TODO : move to Duration
|
||||||
|
track_id: Some(self.track_id),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
self.position = seeked_to.actual_ts;
|
||||||
|
// TODO : Ok(self.position)
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_packet(&mut self) -> DecoderResult<Option<AudioPacket>> {
|
||||||
|
let packet = match self.format.next_packet() {
|
||||||
|
Ok(packet) => packet,
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("format error: {}", err);
|
||||||
|
return Err(DecoderError::SymphoniaDecoder(e.to_string())),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match self.decoder.decode(&packet) {
|
||||||
|
Ok(audio_buf) => {
|
||||||
|
self.position += packet.frames() as TimeStamp;
|
||||||
|
Ok(Some(packet))
|
||||||
|
}
|
||||||
|
// TODO: Handle non-fatal decoding errors and retry.
|
||||||
|
Err(e) =>
|
||||||
|
return Err(DecoderError::SymphoniaDecoder(e.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue