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]]
|
||||
name = "pin-project"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
|
||||
checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
|
||||
checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2498,9 +2498,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.6.0"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd3076b5c8cc18138b8f8814895c11eb4de37114a5d127bafdc5e55798ceef37"
|
||||
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
|
@ -2517,9 +2517,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "1.2.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37"
|
||||
checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2539,9 +2539,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.6"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066"
|
||||
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
@ -2567,9 +2567,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.7"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
|
||||
checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
|
|
@ -23,7 +23,7 @@ futures-util = { version = "0.3", default_features = false, features = ["alloc"]
|
|||
log = "0.4"
|
||||
byteorder = "1.4"
|
||||
shell-words = "1.0.0"
|
||||
tokio = { version = "1", features = ["sync"] }
|
||||
tokio = { version = "1", features = ["rt", "rt-multi-thread", "sync"] }
|
||||
zerocopy = { version = "0.3" }
|
||||
|
||||
# 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