mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Fix build on latest rust.
This commit is contained in:
parent
ab7b5ba69d
commit
267ccbe65e
14 changed files with 292 additions and 258 deletions
197
Cargo.lock
generated
197
Cargo.lock
generated
|
@ -2,27 +2,51 @@
|
|||
name = "librespot"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.12 (git+https://github.com/Manishearth/rust-clippy.git)",
|
||||
"eventual 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"librespot-protocol 0.1.0",
|
||||
"mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"portaudio 0.1.2 (git+https://github.com/mvdnes/portaudio-rs)",
|
||||
"protobuf 1.0.1 (git+https://github.com/plietar/rust-protobuf.git)",
|
||||
"protobuf_macros 0.1.0 (git+https://github.com/plietar/rust-protobuf-macros.git)",
|
||||
"rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)",
|
||||
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rpassword 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rust-crypto 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rust-gmp 0.2.0 (git+https://github.com/plietar/rust-gmp.git)",
|
||||
"shannon 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
|
||||
"tempfile 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vergen 0.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vorbis 0.0.11 (git+https://github.com/plietar/vorbis-rs)",
|
||||
"tempfile 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vergen 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vorbis 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "advapi32-sys"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bit-vec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.1.1"
|
||||
|
@ -35,39 +59,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "0.3.11"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "clippy"
|
||||
version = "0.0.12"
|
||||
source = "git+https://github.com/Manishearth/rust-clippy.git#d3da9f6c81dd3e026bd679c09cea1d6b337ccd25"
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.11"
|
||||
name = "eventual"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syncbox 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.1.2"
|
||||
name = "gcc"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.1.11"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.1.8"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -80,10 +120,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -93,11 +133,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.25"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -105,8 +145,8 @@ name = "ogg-sys"
|
|||
version = "0.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -121,7 +161,7 @@ version = "0.1.2"
|
|||
source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
|
||||
dependencies = [
|
||||
"bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"portaudio_sys 0.1.0 (git+https://github.com/mvdnes/portaudio-rs)",
|
||||
]
|
||||
|
||||
|
@ -130,7 +170,7 @@ name = "portaudio_sys"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
|
||||
dependencies = [
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -142,14 +182,16 @@ source = "git+https://github.com/plietar/rust-protobuf.git#dae87e292a52a66da7f78
|
|||
[[package]]
|
||||
name = "protobuf_macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/plietar/rust-protobuf-macros.git#3b49de3937a34b7a21be1d13caea4348a93c6de4"
|
||||
source = "git+https://github.com/plietar/rust-protobuf-macros.git#2b6a8129e015945300cb2bb7efae2ed78042ed48"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.8"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -162,10 +204,10 @@ name = "rpassword"
|
|||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termios 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -173,24 +215,24 @@ name = "rust-crypto"
|
|||
version = "0.2.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-gmp"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/plietar/rust-gmp.git#cc003c224559f6035cd34a7ed5c6284a49785816"
|
||||
source = "git+https://github.com/plietar/rust-gmp.git#d1bb4448fdbfa2505edadb83b6aac6257fe08ba2"
|
||||
dependencies = [
|
||||
"num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.15"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -198,7 +240,7 @@ name = "shannon"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
|
||||
dependencies = [
|
||||
"byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)",
|
||||
"shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
|
||||
]
|
||||
|
@ -208,18 +250,27 @@ name = "shannon-sys"
|
|||
version = "0.1.0"
|
||||
source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
|
||||
dependencies = [
|
||||
"gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syncbox"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "1.0.0"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -227,34 +278,34 @@ name = "termios"
|
|||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.30"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vergen"
|
||||
version = "0.0.13"
|
||||
version = "0.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vorbis"
|
||||
version = "0.0.11"
|
||||
source = "git+https://github.com/plietar/vorbis-rs#78058c3341832969030f49cbc4b8bc9deb376776"
|
||||
version = "0.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vorbisfile-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -265,8 +316,8 @@ name = "vorbis-sys"
|
|||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -276,8 +327,8 @@ name = "vorbisfile-sys"
|
|||
version = "0.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -285,19 +336,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
|
|
32
Cargo.toml
32
Cargo.toml
|
@ -16,17 +16,22 @@ path = "src/main.rs"
|
|||
path = "protocol"
|
||||
|
||||
[dependencies]
|
||||
mod_path = "*"
|
||||
byteorder = "*"
|
||||
num = "*"
|
||||
rand = "*"
|
||||
lazy_static = "0.1.*"
|
||||
rust-crypto = "*"
|
||||
time = "*"
|
||||
tempfile = "*"
|
||||
rpassword = "*"
|
||||
getopts = "0.2.4"
|
||||
bit-set = "~0.2.0"
|
||||
byteorder = "~0.3.13"
|
||||
eventual = "~0.1.4"
|
||||
getopts = "~0.2.14"
|
||||
lazy_static = "~0.1.14"
|
||||
mod_path = "~0.1.5"
|
||||
num = "~0.1.27"
|
||||
rand = "~0.3.11"
|
||||
rpassword = "~0.0.5"
|
||||
rust-crypto = "~0.2.31"
|
||||
time = "~0.1.32"
|
||||
tempfile = "~1.1.1"
|
||||
vorbis = "~0.0.12"
|
||||
|
||||
[dependencies.clippy]
|
||||
git = "https://github.com/Manishearth/rust-clippy.git"
|
||||
[dependencies.protobuf]
|
||||
git = "https://github.com/plietar/rust-protobuf.git"
|
||||
[dependencies.protobuf_macros]
|
||||
|
@ -35,12 +40,9 @@ git = "https://github.com/plietar/rust-protobuf-macros.git"
|
|||
git = "https://github.com/plietar/rust-gmp.git"
|
||||
[dependencies.shannon]
|
||||
git = "https://github.com/plietar/rust-shannon.git"
|
||||
[dependencies.readall]
|
||||
git = "https://github.com/plietar/rust-readall.git"
|
||||
[dependencies.portaudio]
|
||||
git = "https://github.com/mvdnes/portaudio-rs"
|
||||
[dependencies.vorbis]
|
||||
git = "https://github.com/plietar/vorbis-rs"
|
||||
|
||||
[build-dependencies]
|
||||
vergen = "*"
|
||||
vergen = "~0.0.16"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use bit_set::BitSet;
|
||||
use byteorder::{ByteOrder, BigEndian};
|
||||
use std::cmp::min;
|
||||
use std::collections::BitSet;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::sync::mpsc::{self, TryRecvError};
|
||||
use std::thread;
|
||||
|
@ -9,27 +9,24 @@ use std::io::{self, Read, Write, Seek, SeekFrom};
|
|||
use std::path::PathBuf;
|
||||
use tempfile::TempFile;
|
||||
|
||||
use stream::StreamEvent;
|
||||
use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing};
|
||||
use session::Session;
|
||||
use stream::StreamEvent;
|
||||
|
||||
const CHUNK_SIZE : usize = 0x20000;
|
||||
|
||||
pub enum AudioFile<'s> {
|
||||
pub enum AudioFile {
|
||||
Direct(fs::File),
|
||||
Loading(AudioFileLoading<'s>)
|
||||
Loading(AudioFileLoading)
|
||||
}
|
||||
|
||||
pub struct AudioFileLoading<'s> {
|
||||
pub struct AudioFileLoading {
|
||||
read_file: TempFile,
|
||||
|
||||
position: u64,
|
||||
seek: mpsc::Sender<u64>,
|
||||
|
||||
shared: Arc<AudioFileShared>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
thread: thread::JoinGuard<'s, ()>,
|
||||
}
|
||||
|
||||
struct AudioFileShared {
|
||||
|
@ -40,7 +37,7 @@ struct AudioFileShared {
|
|||
bitmap: Mutex<BitSet>,
|
||||
}
|
||||
|
||||
impl <'s> AudioFileLoading<'s> {
|
||||
impl AudioFileLoading {
|
||||
fn new(session: &Session, file_id: FileId) -> AudioFileLoading {
|
||||
let mut files_iter = TempFile::shared(2).unwrap().into_iter();
|
||||
let read_file = files_iter.next().unwrap();
|
||||
|
@ -70,17 +67,20 @@ impl <'s> AudioFileLoading<'s> {
|
|||
|
||||
let (seek_tx, seek_rx) = mpsc::channel();
|
||||
|
||||
let _shared = shared.clone();
|
||||
let _session = session.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
AudioFileLoading::fetch(&_session, _shared, write_file, seek_rx)
|
||||
});
|
||||
|
||||
AudioFileLoading {
|
||||
read_file: read_file,
|
||||
|
||||
position: 0,
|
||||
seek: seek_tx,
|
||||
|
||||
shared: shared.clone(),
|
||||
|
||||
thread: thread::scoped(move || {
|
||||
AudioFileLoading::fetch(session, shared, write_file, seek_rx)
|
||||
})
|
||||
shared: shared
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ impl <'s> AudioFileLoading<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
impl <'s> Read for AudioFileLoading<'s> {
|
||||
impl Read for AudioFileLoading {
|
||||
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
|
||||
let index = self.position as usize / CHUNK_SIZE;
|
||||
let offset = self.position as usize % CHUNK_SIZE;
|
||||
|
@ -167,15 +167,15 @@ impl <'s> Read for AudioFileLoading<'s> {
|
|||
}
|
||||
drop(bitmap);
|
||||
|
||||
let len = try!(self.read_file.read(&mut output[..len]));
|
||||
let read_len = try!(self.read_file.read(&mut output[..len]));
|
||||
|
||||
self.position += len as u64;
|
||||
self.position += read_len as u64;
|
||||
|
||||
Ok(len)
|
||||
Ok(read_len)
|
||||
}
|
||||
}
|
||||
|
||||
impl <'s> Seek for AudioFileLoading<'s> {
|
||||
impl Seek for AudioFileLoading {
|
||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||
self.position = try!(self.read_file.seek(pos));
|
||||
|
||||
|
@ -189,7 +189,7 @@ impl <'s> Seek for AudioFileLoading<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
impl <'s> Read for AudioFile<'s> {
|
||||
impl Read for AudioFile {
|
||||
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
|
||||
match *self {
|
||||
AudioFile::Direct(ref mut file) => file.read(output),
|
||||
|
@ -198,7 +198,7 @@ impl <'s> Read for AudioFile<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
impl <'s> Seek for AudioFile<'s> {
|
||||
impl Seek for AudioFile {
|
||||
fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
|
||||
match *self {
|
||||
AudioFile::Direct(ref mut file) => file.seek(pos),
|
||||
|
@ -215,7 +215,7 @@ impl AudioFileManager {
|
|||
|
||||
pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf {
|
||||
let name = file_id.to_base16();
|
||||
session.config.cache_location.join(&name[0..2])
|
||||
session.0.config.cache_location.join(&name[0..2])
|
||||
}
|
||||
|
||||
pub fn cache_path(session: &Session, file_id: FileId) -> PathBuf {
|
||||
|
@ -223,7 +223,7 @@ impl AudioFileManager {
|
|||
AudioFileManager::cache_dir(session, file_id).join(&name[2..])
|
||||
}
|
||||
|
||||
pub fn request<'a> (&mut self, session: &'a Session, file_id: FileId) -> AudioFile<'a> {
|
||||
pub fn request (&mut self, session: &Session, file_id: FileId) -> AudioFile {
|
||||
match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
|
||||
Ok(f) => AudioFile::Direct(f),
|
||||
Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id))
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use std::collections::{HashMap, LinkedList};
|
||||
use std::sync::{mpsc, Future};
|
||||
use std::io::{Cursor, Write};
|
||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
|
||||
use readall::ReadAllExt;
|
||||
use eventual;
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Cursor, Read, Write};
|
||||
use std::mem;
|
||||
|
||||
use util::{SpotifyId, FileId, IgnoreExt};
|
||||
use util::{SpotifyId, FileId};
|
||||
use session::Session;
|
||||
use connection::PacketHandler;
|
||||
|
||||
|
@ -15,7 +14,7 @@ pub type AudioKey = [u8; 16];
|
|||
struct AudioKeyId(SpotifyId, FileId);
|
||||
|
||||
enum AudioKeyStatus {
|
||||
Loading(LinkedList<mpsc::Sender<AudioKey>>),
|
||||
Loading(Vec<eventual::Complete<AudioKey, ()>>),
|
||||
Loaded(AudioKey)
|
||||
}
|
||||
|
||||
|
@ -35,17 +34,17 @@ impl AudioKeyManager {
|
|||
}
|
||||
|
||||
pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
|
||||
-> Future<AudioKey> {
|
||||
-> eventual::Future<AudioKey, ()> {
|
||||
|
||||
let id = AudioKeyId(track, file);
|
||||
self.cache.get_mut(&id).map(|status| match status {
|
||||
&mut AudioKeyStatus::Loaded(key) => {
|
||||
Future::from_value(key.clone())
|
||||
self.cache.get_mut(&id).map(|status| match *status {
|
||||
AudioKeyStatus::Loaded(key) => {
|
||||
eventual::Future::of(key.clone())
|
||||
}
|
||||
&mut AudioKeyStatus::Loading(ref mut req) => {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
req.push_front(tx);
|
||||
Future::from_receiver(rx)
|
||||
AudioKeyStatus::Loading(ref mut req) => {
|
||||
let (tx, rx) = eventual::Future::pair();
|
||||
req.push(tx);
|
||||
rx
|
||||
}
|
||||
}).unwrap_or_else(|| {
|
||||
let seq = self.next_seq;
|
||||
|
@ -61,11 +60,9 @@ impl AudioKeyManager {
|
|||
|
||||
self.pending.insert(seq, id.clone());
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let mut req = LinkedList::new();
|
||||
req.push_front(tx);
|
||||
self.cache.insert(id, AudioKeyStatus::Loading(req));
|
||||
Future::from_receiver(rx)
|
||||
let (tx, rx) = eventual::Future::pair();
|
||||
self.cache.insert(id, AudioKeyStatus::Loading(vec!{ tx }));
|
||||
rx
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -77,14 +74,14 @@ impl PacketHandler for AudioKeyManager {
|
|||
let mut data = Cursor::new(data);
|
||||
let seq = data.read_u32::<BigEndian>().unwrap();
|
||||
let mut key = [0u8; 16];
|
||||
data.read_all(&mut key).unwrap();
|
||||
data.read_exact(&mut key).unwrap();
|
||||
|
||||
if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) {
|
||||
let status = mem::replace(status, AudioKeyStatus::Loaded(key));
|
||||
|
||||
if let AudioKeyStatus::Loading(cbs) = status {
|
||||
for cb in cbs {
|
||||
cb.send(key).ignore();
|
||||
cb.complete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use byteorder::{self, BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
|
||||
use readall::ReadAllExt;
|
||||
use shannon::ShannonStream;
|
||||
use std::convert;
|
||||
use std::io;
|
||||
use std::io::Write;
|
||||
use std::io::{Read, Write};
|
||||
use std::net::TcpStream;
|
||||
use std::result;
|
||||
|
||||
|
@ -70,7 +69,7 @@ impl PlainConnection {
|
|||
let mut buffer = vec![0u8; size];
|
||||
|
||||
BigEndian::write_u32(&mut buffer, size as u32);
|
||||
try!(self.stream.read_all(&mut buffer[4..]));
|
||||
try!(self.stream.read_exact(&mut buffer[4..]));
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
|
@ -98,7 +97,7 @@ impl CipherConnection {
|
|||
let size = try!(self.stream.read_u16::<BigEndian>()) as usize;
|
||||
|
||||
let mut data = vec![0; size];
|
||||
try!(self.stream.read_all(&mut data));
|
||||
try!(self.stream.read_exact(&mut data));
|
||||
|
||||
try!(self.stream.finish_recv());
|
||||
|
||||
|
|
12
src/lib.rs
12
src/lib.rs
|
@ -1,25 +1,25 @@
|
|||
#![crate_name = "librespot"]
|
||||
|
||||
#![feature(plugin,scoped,zero_one,iter_arith,slice_position_elem,slice_bytes,bitset,arc_weak,append,future,mpsc_select)]
|
||||
#![allow(deprecated)]
|
||||
//#![allow(unused_imports,dead_code)]
|
||||
#![feature(plugin,read_exact,zero_one,iter_arith,slice_bytes,arc_weak,append,mpsc_select)]
|
||||
#![allow(needless_return)]
|
||||
|
||||
#![plugin(clippy)]
|
||||
#![plugin(protobuf_macros)]
|
||||
#[macro_use] extern crate lazy_static;
|
||||
|
||||
|
||||
extern crate bit_set;
|
||||
extern crate byteorder;
|
||||
extern crate crypto;
|
||||
extern crate eventual;
|
||||
extern crate gmp;
|
||||
extern crate num;
|
||||
extern crate portaudio;
|
||||
extern crate protobuf;
|
||||
extern crate shannon;
|
||||
extern crate rand;
|
||||
extern crate readall;
|
||||
extern crate vorbis;
|
||||
extern crate time;
|
||||
extern crate tempfile;
|
||||
extern crate vorbis;
|
||||
|
||||
extern crate librespot_protocol;
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(scoped)]
|
||||
#![feature(result_expect)]
|
||||
#![allow(deprecated)]
|
||||
|
||||
|
@ -71,9 +70,10 @@ fn main() {
|
|||
session.login(username.clone(), password);
|
||||
session.poll();
|
||||
|
||||
let poll_thread = thread::scoped(|| {
|
||||
let _session = session.clone();
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
session.poll();
|
||||
_session.poll();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -81,7 +81,5 @@ fn main() {
|
|||
|
||||
let mut spirc_manager = SpircManager::new(&session, player, username, name);
|
||||
spirc_manager.run();
|
||||
|
||||
poll_thread.join();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
|
||||
use eventual;
|
||||
use protobuf::{self, Message};
|
||||
use readall::ReadAllExt;
|
||||
use std::collections::{HashMap, LinkedList};
|
||||
use std::collections::HashMap;
|
||||
use std::io::{Cursor, Read, Write};
|
||||
use std::fmt;
|
||||
use std::mem::replace;
|
||||
use std::sync::{mpsc, Future};
|
||||
use std::sync::mpsc;
|
||||
|
||||
use librespot_protocol as protocol;
|
||||
use session::Session;
|
||||
|
@ -30,13 +29,13 @@ pub struct MercuryRequest {
|
|||
#[derive(Debug)]
|
||||
pub struct MercuryResponse {
|
||||
pub uri: String,
|
||||
pub payload: LinkedList<Vec<u8>>
|
||||
pub payload: Vec<Vec<u8>>
|
||||
}
|
||||
|
||||
pub struct MercuryPending {
|
||||
parts: LinkedList<Vec<u8>>,
|
||||
parts: Vec<Vec<u8>>,
|
||||
partial: Option<Vec<u8>>,
|
||||
callback: Option<mpsc::Sender<MercuryResponse>>
|
||||
callback: Option<eventual::Complete<MercuryResponse, ()>>
|
||||
}
|
||||
|
||||
pub struct MercuryManager {
|
||||
|
@ -45,14 +44,14 @@ pub struct MercuryManager {
|
|||
subscriptions: HashMap<String, mpsc::Sender<MercuryResponse>>,
|
||||
}
|
||||
|
||||
impl fmt::Display for MercuryMethod {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
formatter.write_str(match *self {
|
||||
impl ToString for MercuryMethod {
|
||||
fn to_string(&self) -> String {
|
||||
match *self {
|
||||
MercuryMethod::GET => "GET",
|
||||
MercuryMethod::SUB => "SUB",
|
||||
MercuryMethod::UNSUB => "UNSUB",
|
||||
MercuryMethod::SEND => "SEND"
|
||||
})
|
||||
}.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +65,7 @@ impl MercuryManager {
|
|||
}
|
||||
|
||||
pub fn request(&mut self, session: &Session, req: MercuryRequest)
|
||||
-> Future<MercuryResponse> {
|
||||
-> eventual::Future<MercuryResponse, ()> {
|
||||
|
||||
let mut seq = [0u8; 4];
|
||||
BigEndian::write_u32(&mut seq, self.next_seq);
|
||||
|
@ -81,14 +80,14 @@ impl MercuryManager {
|
|||
|
||||
session.send_packet(cmd, &data).unwrap();
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let (tx, rx) = eventual::Future::pair();
|
||||
self.pending.insert(seq.to_vec(), MercuryPending{
|
||||
parts: LinkedList::new(),
|
||||
parts: Vec::new(),
|
||||
partial: None,
|
||||
callback: Some(tx),
|
||||
});
|
||||
|
||||
Future::from_receiver(rx)
|
||||
rx
|
||||
}
|
||||
|
||||
pub fn subscribe(&mut self, session: &Session, uri: String)
|
||||
|
@ -109,33 +108,25 @@ impl MercuryManager {
|
|||
fn parse_part(mut s: &mut Read) -> Vec<u8> {
|
||||
let size = s.read_u16::<BigEndian>().unwrap() as usize;
|
||||
let mut buffer = vec![0; size];
|
||||
s.read_all(&mut buffer).unwrap();
|
||||
s.read_exact(&mut buffer).unwrap();
|
||||
|
||||
buffer
|
||||
}
|
||||
|
||||
fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) {
|
||||
let header_data = match pending.parts.pop_front() {
|
||||
Some(data) => data,
|
||||
None => panic!("No header part !")
|
||||
};
|
||||
|
||||
let header_data = pending.parts.remove(0);
|
||||
let header : protocol::mercury::Header =
|
||||
protobuf::parse_from_bytes(&header_data).unwrap();
|
||||
|
||||
let callback = if cmd == 0xb5 {
|
||||
self.subscriptions.get(header.get_uri())
|
||||
} else {
|
||||
pending.callback.as_ref()
|
||||
let response = MercuryResponse {
|
||||
uri: header.get_uri().to_owned(),
|
||||
payload: pending.parts
|
||||
};
|
||||
|
||||
if let Some(ref ch) = callback {
|
||||
// Ignore send error.
|
||||
// It simply means the receiver was closed
|
||||
ch.send(MercuryResponse{
|
||||
uri: header.get_uri().to_string(),
|
||||
payload: pending.parts
|
||||
}).ignore();
|
||||
if cmd == 0xb5 {
|
||||
self.subscriptions.get(header.get_uri()).map(|ch| ch.send(response).ignore());
|
||||
} else {
|
||||
pending.callback.map(|cb| cb.complete(response));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +164,7 @@ impl PacketHandler for MercuryManager {
|
|||
let seq = {
|
||||
let seq_length = packet.read_u16::<BigEndian>().unwrap() as usize;
|
||||
let mut seq = vec![0; seq_length];
|
||||
packet.read_all(&mut seq).unwrap();
|
||||
packet.read_exact(&mut seq).unwrap();
|
||||
seq
|
||||
};
|
||||
let flags = packet.read_u8().unwrap();
|
||||
|
@ -183,7 +174,7 @@ impl PacketHandler for MercuryManager {
|
|||
pending
|
||||
} else if cmd == 0xb5 {
|
||||
MercuryPending {
|
||||
parts: LinkedList::new(),
|
||||
parts: Vec::new(),
|
||||
partial: None,
|
||||
callback: None,
|
||||
}
|
||||
|
@ -202,7 +193,7 @@ impl PacketHandler for MercuryManager {
|
|||
if i == count - 1 && (flags == 2) {
|
||||
pending.partial = Some(part)
|
||||
} else {
|
||||
pending.parts.push_back(part);
|
||||
pending.parts.push(part);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use eventual::Async;
|
||||
use protobuf::{self, Message};
|
||||
use std::any::{Any, TypeId};
|
||||
use std::collections::HashMap;
|
||||
|
@ -11,7 +12,7 @@ use mercury::{MercuryRequest, MercuryMethod};
|
|||
use util::{SpotifyId, FileId};
|
||||
use session::Session;
|
||||
|
||||
pub trait MetadataTrait : Send + Any + 'static {
|
||||
pub trait MetadataTrait : Send + Sized + Any + 'static {
|
||||
type Message: protobuf::MessageStatic;
|
||||
fn from_msg(msg: &Self::Message) -> Self;
|
||||
fn base_url() -> &'static str;
|
||||
|
@ -29,7 +30,7 @@ impl MetadataTrait for Track {
|
|||
type Message = protocol::metadata::Track;
|
||||
fn from_msg(msg: &Self::Message) -> Self {
|
||||
Track {
|
||||
name: msg.get_name().to_string(),
|
||||
name: msg.get_name().to_owned(),
|
||||
album: SpotifyId::from_raw(msg.get_album().get_gid()),
|
||||
files: msg.get_file().iter()
|
||||
.map(|file| {
|
||||
|
@ -59,7 +60,7 @@ impl MetadataTrait for Album {
|
|||
type Message = protocol::metadata::Album;
|
||||
fn from_msg(msg: &Self::Message) -> Self {
|
||||
Album {
|
||||
name: msg.get_name().to_string(),
|
||||
name: msg.get_name().to_owned(),
|
||||
artists: msg.get_artist().iter()
|
||||
.map(|a| SpotifyId::from_raw(a.get_gid()))
|
||||
.collect(),
|
||||
|
@ -89,7 +90,7 @@ impl MetadataTrait for Artist {
|
|||
type Message = protocol::metadata::Artist;
|
||||
fn from_msg(msg: &Self::Message) -> Self {
|
||||
Artist {
|
||||
name: msg.get_name().to_string(),
|
||||
name: msg.get_name().to_owned(),
|
||||
}
|
||||
}
|
||||
fn base_url() -> &'static str {
|
||||
|
@ -164,7 +165,7 @@ impl <T: MetadataTrait> MetadataState<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unwrap<'s>(&'s self) -> &'s T {
|
||||
pub fn unwrap(&self) -> &T {
|
||||
match *self {
|
||||
MetadataState::Loaded(ref data) => data,
|
||||
_ => panic!("Not loaded")
|
||||
|
@ -180,7 +181,7 @@ pub enum MetadataRequest {
|
|||
}
|
||||
|
||||
pub struct MetadataManager {
|
||||
cache: HashMap<(SpotifyId, TypeId), Box<Any + Send>>
|
||||
cache: HashMap<(SpotifyId, TypeId), Box<Any + Send + 'static>>
|
||||
}
|
||||
|
||||
impl MetadataManager {
|
||||
|
@ -204,7 +205,7 @@ impl MetadataManager {
|
|||
cond: Condvar::new()
|
||||
});
|
||||
|
||||
self.cache.insert(key, Box::new(x.downgrade()));
|
||||
self.cache.insert(key, Box::new(Arc::downgrade(&x)));
|
||||
self.load(session, x.clone());
|
||||
x
|
||||
})
|
||||
|
@ -219,10 +220,10 @@ impl MetadataManager {
|
|||
});
|
||||
|
||||
thread::spawn(move || {
|
||||
let response = rx.into_inner();
|
||||
let response = rx.await().unwrap();
|
||||
|
||||
let msg : T::Message = protobuf::parse_from_bytes(
|
||||
response.payload.front().unwrap()).unwrap();
|
||||
response.payload.first().unwrap()).unwrap();
|
||||
|
||||
object.set(MetadataState::Loaded(T::from_msg(&msg)));
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use eventual::Async;
|
||||
use portaudio;
|
||||
use vorbis;
|
||||
use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard};
|
||||
use std::thread;
|
||||
use vorbis;
|
||||
|
||||
use metadata::TrackRef;
|
||||
use session::Session;
|
||||
|
@ -9,13 +10,10 @@ use audio_decrypt::AudioDecrypt;
|
|||
use util::{self, SpotifyId, Subfile};
|
||||
use spirc::{SpircState, SpircDelegate, PlayStatus};
|
||||
|
||||
pub struct Player<'s> {
|
||||
pub struct Player {
|
||||
state: Arc<(Mutex<PlayerState>, Condvar)>,
|
||||
|
||||
commands: mpsc::Sender<PlayerCommand>,
|
||||
|
||||
#[allow(dead_code)]
|
||||
thread: thread::JoinGuard<'s, ()>,
|
||||
}
|
||||
|
||||
pub struct PlayerState {
|
||||
|
@ -27,10 +25,9 @@ pub struct PlayerState {
|
|||
end_of_track: bool
|
||||
}
|
||||
|
||||
struct PlayerInternal<'s> {
|
||||
struct PlayerInternal {
|
||||
state: Arc<(Mutex<PlayerState>, Condvar)>,
|
||||
|
||||
session: &'s Session,
|
||||
session: Session,
|
||||
commands: mpsc::Receiver<PlayerCommand>,
|
||||
}
|
||||
|
||||
|
@ -42,7 +39,7 @@ enum PlayerCommand {
|
|||
Seek(u32)
|
||||
}
|
||||
|
||||
impl <'s> Player<'s> {
|
||||
impl Player {
|
||||
pub fn new(session: &Session) -> Player {
|
||||
let (cmd_tx, cmd_rx) = mpsc::channel();
|
||||
|
||||
|
@ -55,17 +52,18 @@ impl <'s> Player<'s> {
|
|||
}), Condvar::new()));
|
||||
|
||||
let internal = PlayerInternal {
|
||||
session: session,
|
||||
session: session.clone(),
|
||||
commands: cmd_rx,
|
||||
state: state.clone()
|
||||
};
|
||||
|
||||
thread::spawn(move || {
|
||||
internal.run()
|
||||
});
|
||||
|
||||
Player {
|
||||
commands: cmd_tx,
|
||||
state: state,
|
||||
thread: thread::scoped(move || {
|
||||
internal.run()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +72,7 @@ impl <'s> Player<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
impl <'s> PlayerInternal<'s> {
|
||||
impl PlayerInternal {
|
||||
fn run(self) {
|
||||
portaudio::initialize().unwrap();
|
||||
|
||||
|
@ -102,7 +100,8 @@ impl <'s> PlayerInternal<'s> {
|
|||
|
||||
let track : TrackRef = self.session.metadata(id);
|
||||
let file_id = *track.wait().unwrap().files.first().unwrap();
|
||||
let key = self.session.audio_key(track.id(), file_id).into_inner();
|
||||
|
||||
let key = self.session.audio_key(track.id(), file_id).await().unwrap();
|
||||
decoder = Some(
|
||||
vorbis::Decoder::new(
|
||||
Subfile::new(
|
||||
|
@ -217,7 +216,7 @@ impl <'s> PlayerInternal<'s> {
|
|||
}
|
||||
}
|
||||
|
||||
impl <'s> SpircDelegate for Player<'s> {
|
||||
impl SpircDelegate for Player {
|
||||
type State = PlayerState;
|
||||
|
||||
fn load(&self, track: SpotifyId,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crypto::digest::Digest;
|
||||
use crypto::sha1::Sha1;
|
||||
use eventual::Future;
|
||||
use protobuf::{self, Message};
|
||||
use rand::thread_rng;
|
||||
use std::sync::{Mutex, Arc, Future, mpsc};
|
||||
use std::sync::{Mutex, Arc, mpsc};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use connection::{self, PlainConnection, CipherConnection};
|
||||
|
@ -26,7 +27,7 @@ pub struct Config {
|
|||
pub cache_location: PathBuf,
|
||||
}
|
||||
|
||||
pub struct Session {
|
||||
pub struct SessionData {
|
||||
pub config: Config,
|
||||
|
||||
mercury: Mutex<MercuryManager>,
|
||||
|
@ -38,7 +39,8 @@ pub struct Session {
|
|||
tx_connection: Mutex<CipherConnection>,
|
||||
}
|
||||
|
||||
type SessionRef = Arc<Session>;
|
||||
#[derive(Clone)]
|
||||
pub struct Session(pub Arc<SessionData>);
|
||||
|
||||
impl Session {
|
||||
pub fn new(mut config: Config) -> Session {
|
||||
|
@ -114,7 +116,7 @@ impl Session {
|
|||
|
||||
let cipher_connection = connection.setup_cipher(shared_keys);
|
||||
|
||||
Session {
|
||||
Session(Arc::new(SessionData {
|
||||
config: config,
|
||||
|
||||
rx_connection: Mutex::new(cipher_connection.clone()),
|
||||
|
@ -125,7 +127,7 @@ impl Session {
|
|||
stream: Mutex::new(StreamManager::new()),
|
||||
audio_key: Mutex::new(AudioKeyManager::new()),
|
||||
audio_file: Mutex::new(AudioFileManager::new()),
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn login(&self, username: String, password: String) {
|
||||
|
@ -138,15 +140,15 @@ impl Session {
|
|||
system_info => {
|
||||
cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN,
|
||||
os: protocol::authentication::Os::OS_UNKNOWN,
|
||||
system_information_string: "librespot".to_string(),
|
||||
device_id: self.config.device_id.clone()
|
||||
system_information_string: "librespot".to_owned(),
|
||||
device_id: self.0.config.device_id.clone()
|
||||
},
|
||||
version_string: util::version::version_string(),
|
||||
appkey => {
|
||||
version: self.config.application_key[0] as u32,
|
||||
devkey: self.config.application_key[0x1..0x81].to_vec(),
|
||||
signature: self.config.application_key[0x81..0x141].to_vec(),
|
||||
useragent: self.config.user_agent.clone(),
|
||||
version: self.0.config.application_key[0] as u32,
|
||||
devkey: self.0.config.application_key[0x1..0x81].to_vec(),
|
||||
signature: self.0.config.application_key[0x81..0x141].to_vec(),
|
||||
useragent: self.0.config.user_agent.clone(),
|
||||
callback_hash: vec![0; 20],
|
||||
}
|
||||
});
|
||||
|
@ -156,14 +158,14 @@ impl Session {
|
|||
|
||||
pub fn poll(&self) {
|
||||
let (cmd, data) =
|
||||
self.rx_connection.lock().unwrap().recv_packet().unwrap();
|
||||
self.0.rx_connection.lock().unwrap().recv_packet().unwrap();
|
||||
|
||||
match cmd {
|
||||
0x4 => self.send_packet(0x49, &data).unwrap(),
|
||||
0x4a => (),
|
||||
0x9 => self.stream.lock().unwrap().handle(cmd, data),
|
||||
0xd | 0xe => self.audio_key.lock().unwrap().handle(cmd, data),
|
||||
0xb2...0xb6 => self.mercury.lock().unwrap().handle(cmd, data),
|
||||
0x9 => self.0.stream.lock().unwrap().handle(cmd, data),
|
||||
0xd | 0xe => self.0.audio_key.lock().unwrap().handle(cmd, data),
|
||||
0xb2...0xb6 => self.0.mercury.lock().unwrap().handle(cmd, data),
|
||||
0xac => eprintln!("Authentication succeedded"),
|
||||
0xad => eprintln!("Authentication failed"),
|
||||
_ => ()
|
||||
|
@ -171,31 +173,31 @@ impl Session {
|
|||
}
|
||||
|
||||
pub fn send_packet(&self, cmd: u8, data: &[u8]) -> connection::Result<()> {
|
||||
self.tx_connection.lock().unwrap().send_packet(cmd, data)
|
||||
self.0.tx_connection.lock().unwrap().send_packet(cmd, data)
|
||||
}
|
||||
|
||||
pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future<AudioKey> {
|
||||
self.audio_key.lock().unwrap().request(self, track, file)
|
||||
pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future<AudioKey, ()> {
|
||||
self.0.audio_key.lock().unwrap().request(self, track, file)
|
||||
}
|
||||
|
||||
pub fn audio_file(&self, file: FileId) -> AudioFile {
|
||||
self.audio_file.lock().unwrap().request(self, file)
|
||||
self.0.audio_file.lock().unwrap().request(self, file)
|
||||
}
|
||||
|
||||
pub fn stream(&self, file: FileId, offset: u32, size: u32) -> mpsc::Receiver<StreamEvent> {
|
||||
self.stream.lock().unwrap().request(self, file, offset, size)
|
||||
self.0.stream.lock().unwrap().request(self, file, offset, size)
|
||||
}
|
||||
|
||||
pub fn metadata<T: MetadataTrait>(&self, id: SpotifyId) -> MetadataRef<T> {
|
||||
self.metadata.lock().unwrap().get(self, id)
|
||||
self.0.metadata.lock().unwrap().get(self, id)
|
||||
}
|
||||
|
||||
pub fn mercury(&self, req: MercuryRequest) -> Future<MercuryResponse> {
|
||||
self.mercury.lock().unwrap().request(self, req)
|
||||
pub fn mercury(&self, req: MercuryRequest) -> Future<MercuryResponse, ()> {
|
||||
self.0.mercury.lock().unwrap().request(self, req)
|
||||
}
|
||||
|
||||
pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver<MercuryResponse> {
|
||||
self.mercury.lock().unwrap().subscribe(self, uri)
|
||||
self.0.mercury.lock().unwrap().subscribe(self, uri)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
38
src/spirc.rs
38
src/spirc.rs
|
@ -1,3 +1,4 @@
|
|||
use eventual::Async;
|
||||
use protobuf::{self, Message};
|
||||
use std::sync::{mpsc, MutexGuard};
|
||||
|
||||
|
@ -70,7 +71,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
|
|||
seq_nr: 0,
|
||||
|
||||
name: name,
|
||||
ident: session.config.device_id.clone(),
|
||||
ident: session.0.config.device_id.clone(),
|
||||
device_type: 5,
|
||||
can_play: true,
|
||||
|
||||
|
@ -97,7 +98,8 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
|
|||
select! {
|
||||
pkt = rx.recv() => {
|
||||
let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>(
|
||||
pkt.unwrap().payload.front().unwrap()).unwrap();
|
||||
pkt.unwrap().payload.first().unwrap()).unwrap();
|
||||
|
||||
println!("{:?} {} {} {} {}",
|
||||
frame.get_typ(),
|
||||
frame.get_device_state().get_name(),
|
||||
|
@ -127,7 +129,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
|
|||
|
||||
fn handle(&mut self, frame: protocol::spirc::Frame) {
|
||||
if frame.get_recipient().len() > 0 {
|
||||
self.last_command_ident = frame.get_ident().to_string();
|
||||
self.last_command_ident = frame.get_ident().to_owned();
|
||||
self.last_command_msgid = frame.get_seq_nr();
|
||||
}
|
||||
match frame.get_typ() {
|
||||
|
@ -174,12 +176,12 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
|
|||
let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), {
|
||||
version: 1,
|
||||
ident: self.ident.clone(),
|
||||
protocol_version: "2.0.0".to_string(),
|
||||
protocol_version: "2.0.0".to_owned(),
|
||||
seq_nr: { self.seq_nr += 1; self.seq_nr },
|
||||
typ: protocol::spirc::MessageType::kMessageTypeNotify,
|
||||
device_state: self.device_state(),
|
||||
recipient: protobuf::RepeatedField::from_vec(
|
||||
recipient.map(|r| vec![r.to_string()] ).unwrap_or(vec![])
|
||||
recipient.map(|r| vec![r.to_owned()] ).unwrap_or(vec![])
|
||||
),
|
||||
state_update_id: self.state_update_id as i64
|
||||
});
|
||||
|
@ -193,7 +195,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
|
|||
uri: format!("hm://remote/user/{}", self.username),
|
||||
content_type: None,
|
||||
payload: vec![ pkt.write_to_bytes().unwrap() ]
|
||||
});
|
||||
}).await().unwrap();
|
||||
}
|
||||
|
||||
fn spirc_state(&self) -> protocol::spirc::State {
|
||||
|
@ -259,23 +261,23 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
|
|||
@{
|
||||
typ: protocol::spirc::CapabilityType::kSupportedContexts,
|
||||
stringValue => [
|
||||
"album".to_string(),
|
||||
"playlist".to_string(),
|
||||
"search".to_string(),
|
||||
"inbox".to_string(),
|
||||
"toplist".to_string(),
|
||||
"starred".to_string(),
|
||||
"publishedstarred".to_string(),
|
||||
"track".to_string(),
|
||||
"album".to_owned(),
|
||||
"playlist".to_owned(),
|
||||
"search".to_owned(),
|
||||
"inbox".to_owned(),
|
||||
"toplist".to_owned(),
|
||||
"starred".to_owned(),
|
||||
"publishedstarred".to_owned(),
|
||||
"track".to_owned(),
|
||||
]
|
||||
},
|
||||
@{
|
||||
typ: protocol::spirc::CapabilityType::kSupportedTypes,
|
||||
stringValue => [
|
||||
"audio/local".to_string(),
|
||||
"audio/track".to_string(),
|
||||
"local".to_string(),
|
||||
"track".to_string(),
|
||||
"audio/local".to_owned(),
|
||||
"audio/track".to_owned(),
|
||||
"local".to_owned(),
|
||||
"track".to_owned(),
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -19,7 +19,7 @@ impl SpotifyId {
|
|||
|
||||
let mut n : u128 = std::num::Zero::zero();
|
||||
for c in data {
|
||||
let d = BASE16_DIGITS.position_elem(c).unwrap() as u8;
|
||||
let d = BASE16_DIGITS.iter().position(|e| e == c).unwrap() as u8;
|
||||
n = n * u128::from(16);
|
||||
n = n + u128::from(d);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ impl SpotifyId {
|
|||
|
||||
let mut n : u128 = std::num::Zero::zero();
|
||||
for c in data {
|
||||
let d = BASE62_DIGITS.position_elem(c).unwrap() as u8;
|
||||
let d = BASE62_DIGITS.iter().position(|e| e == c).unwrap() as u8;
|
||||
n = n * u128::from(62);
|
||||
n = n + u128::from(d);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl SpotifyId {
|
|||
data[15-i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize];
|
||||
}
|
||||
|
||||
std::str::from_utf8(&data).unwrap().to_string()
|
||||
std::str::from_utf8(&data).unwrap().to_owned()
|
||||
}
|
||||
|
||||
pub fn to_raw(&self) -> [u8; 16] {
|
||||
|
|
|
@ -33,8 +33,8 @@ impl io::Read for ZeroFile {
|
|||
// TODO optimize with memset or similar
|
||||
fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
|
||||
let len = min(output.len(), (self.size - self.position) as usize);
|
||||
for i in 0..len {
|
||||
output[i] = 0;
|
||||
for b in output {
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
self.position += len as u64;
|
||||
|
|
Loading…
Reference in a new issue