Update tokio and fix build

This commit is contained in:
Roderick van Domburg 2021-11-27 14:26:13 +01:00
parent f037a42908
commit 47badd61e0
No known key found for this signature in database
GPG key ID: FE2585E713F9F30A
3 changed files with 149 additions and 13 deletions

24
Cargo.lock generated
View file

@ -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",

View file

@ -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

View 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())),
}
}
}