correctly wrap ffmpeg
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -486,7 +486,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "disconic"
|
name = "disconic"
|
||||||
version = "0.1.2-pre.3"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "disconic"
|
name = "disconic"
|
||||||
description = "Discord bot for interacting with subsonic music libraries"
|
description = "Discord bot for interacting with subsonic music libraries"
|
||||||
version = "0.1.2-pre.3"
|
version = "0.2.0"
|
||||||
authors = [ "Gabriel Fontes <eu@misterio.me>" ]
|
authors = [ "Gabriel Fontes <eu@misterio.me>" ]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
homepage = "https://misterio.me"
|
homepage = "https://misterio.me"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ lib, rustPlatform, pkg-config, autoconf, alsa-lib, automake, libopus, ffmpeg }:
|
{ lib, rustPlatform, pkg-config, autoconf, alsa-lib, automake, libopus, ffmpeg, makeWrapper }:
|
||||||
|
|
||||||
let manifest = (lib.importTOML ./Cargo.toml).package;
|
let manifest = (lib.importTOML ./Cargo.toml).package;
|
||||||
in rustPlatform.buildRustPackage rec {
|
in rustPlatform.buildRustPackage rec {
|
||||||
@@ -8,7 +8,7 @@ in rustPlatform.buildRustPackage rec {
|
|||||||
src = lib.cleanSource ./.;
|
src = lib.cleanSource ./.;
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config ];
|
nativeBuildInputs = [ pkg-config ];
|
||||||
buildInputs = [ autoconf alsa-lib automake libopus ffmpeg ];
|
buildInputs = [ autoconf alsa-lib automake libopus makeWrapper ffmpeg ];
|
||||||
|
|
||||||
cargoLock = {
|
cargoLock = {
|
||||||
lockFile = ./Cargo.lock;
|
lockFile = ./Cargo.lock;
|
||||||
@@ -17,6 +17,10 @@ in rustPlatform.buildRustPackage rec {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
postFixup = ''
|
||||||
|
wrapProgram $out/bin/disconic --set PATH ${lib.makeBinPath [ ffmpeg ]}
|
||||||
|
'';
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
description = manifest.desciption;
|
description = manifest.desciption;
|
||||||
homepage = manifest.homepage;
|
homepage = manifest.homepage;
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ use sunk::{
|
|||||||
use crate::MusicClient;
|
use crate::MusicClient;
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[commands(song, random, skip, stop, pause, resume, queue, now_playing, remove)]
|
#[commands(
|
||||||
|
song, random, skip, stop, pause, resume, queue, nowplaying, remove, album
|
||||||
|
)]
|
||||||
pub struct General;
|
pub struct General;
|
||||||
|
|
||||||
pub struct Handler;
|
pub struct Handler;
|
||||||
@@ -31,9 +33,8 @@ impl EventHandler for Handler {}
|
|||||||
#[hook]
|
#[hook]
|
||||||
pub async fn after_hook(ctx: &Context, msg: &Message, cmd_name: &str, error: CommandResult) {
|
pub async fn after_hook(ctx: &Context, msg: &Message, cmd_name: &str, error: CommandResult) {
|
||||||
if let Err(why) = error {
|
if let Err(why) = error {
|
||||||
let text = format!("Error running {}: {:?}", cmd_name, why);
|
msg.reply(&ctx.http, format!("{:?}", why)).await.ok();
|
||||||
msg.reply(&ctx.http, &text).await.ok();
|
eprintln!("{}: {:?}", cmd_name, why,);
|
||||||
eprintln!("{}", &text);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,17 +55,40 @@ async fn song(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
.await?
|
.await?
|
||||||
.songs;
|
.songs;
|
||||||
|
|
||||||
match result.first() {
|
let song = result
|
||||||
Some(song) => {
|
.first()
|
||||||
queue_song(ctx, msg, &song, &music_client).await?;
|
.ok_or_else(|| anyhow!("No song matching search found"))?;
|
||||||
Ok(())
|
queue_song(ctx, msg, &song, &music_client).await?;
|
||||||
}
|
|
||||||
None => {
|
Ok(())
|
||||||
let text = "No song matching search found";
|
}
|
||||||
msg.reply(&ctx.http, text).await?;
|
|
||||||
Err(anyhow!(text).into())
|
#[command]
|
||||||
}
|
#[aliases(a, album)]
|
||||||
|
/// Play a named album
|
||||||
|
async fn album(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
|
let data = ctx.data.read().await;
|
||||||
|
let music_client = data
|
||||||
|
.get::<MusicClient>()
|
||||||
|
.expect("Couldn't retrieve music client");
|
||||||
|
|
||||||
|
let search_size = SearchPage::new().with_size(1);
|
||||||
|
let ignore = search::NONE;
|
||||||
|
|
||||||
|
let result = music_client
|
||||||
|
.search(args.rest(), ignore, search_size, ignore)
|
||||||
|
.await?
|
||||||
|
.albums;
|
||||||
|
|
||||||
|
let album = result
|
||||||
|
.first()
|
||||||
|
.ok_or_else(|| anyhow!("No albums matching search found"))?;
|
||||||
|
|
||||||
|
for song in album.songs(music_client).await? {
|
||||||
|
queue_song(ctx, msg, &song, &music_client).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
@@ -78,41 +102,12 @@ async fn random(ctx: &Context, msg: &Message) -> CommandResult {
|
|||||||
|
|
||||||
let result = Song::random(&music_client, 1).await?;
|
let result = Song::random(&music_client, 1).await?;
|
||||||
|
|
||||||
match result.first() {
|
let song = result
|
||||||
Some(song) => {
|
.first()
|
||||||
queue_song(ctx, msg, &song, &music_client).await?;
|
.ok_or_else(|| anyhow!("No song matching search found"))?;
|
||||||
Ok(())
|
queue_song(ctx, msg, &song, &music_client).await?;
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let text = "No song found";
|
|
||||||
msg.reply(&ctx.http, text).await?;
|
|
||||||
Err(anyhow!(text).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[command]
|
Ok(())
|
||||||
#[aliases(pl)]
|
|
||||||
/// Play a playlist
|
|
||||||
async fn playlist(ctx: &Context, msg: &Message) -> CommandResult {
|
|
||||||
let data = ctx.data.read().await;
|
|
||||||
let music_client = data
|
|
||||||
.get::<MusicClient>()
|
|
||||||
.expect("Couldn't retrieve music client");
|
|
||||||
|
|
||||||
let result = Song::random(&music_client, 1).await?;
|
|
||||||
|
|
||||||
match result.first() {
|
|
||||||
Some(song) => {
|
|
||||||
queue_song(ctx, msg, &song, &music_client).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let text = "No song found";
|
|
||||||
msg.reply(&ctx.http, text).await?;
|
|
||||||
Err(anyhow!(text).into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
@@ -150,14 +145,9 @@ async fn pause(ctx: &Context, msg: &Message) -> CommandResult {
|
|||||||
let handler = call.lock().await;
|
let handler = call.lock().await;
|
||||||
|
|
||||||
let queue = handler.queue();
|
let queue = handler.queue();
|
||||||
let current = match queue.current() {
|
let current = queue
|
||||||
Some(channel) => channel,
|
.current()
|
||||||
None => {
|
.ok_or_else(|| anyhow!("Not currently playing"))?;
|
||||||
let text = "Not currently playing";
|
|
||||||
msg.reply(ctx, text).await?;
|
|
||||||
return Err(anyhow!(text).into());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
current.pause()?;
|
current.pause()?;
|
||||||
|
|
||||||
msg.reply(&ctx.http, "Paused playing").await?;
|
msg.reply(&ctx.http, "Paused playing").await?;
|
||||||
@@ -181,23 +171,19 @@ async fn resume(ctx: &Context, msg: &Message) -> CommandResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[aliases(now_playing, now, np, playing)]
|
#[aliases(nowplaying, now, np, playing)]
|
||||||
/// Show currently playing song
|
/// Show currently playing song
|
||||||
async fn now_playing(ctx: &Context, msg: &Message) -> CommandResult {
|
async fn nowplaying(ctx: &Context, msg: &Message) -> CommandResult {
|
||||||
let call = join_channel(&ctx, &msg).await?;
|
let call = join_channel(&ctx, &msg).await?;
|
||||||
let handler = call.lock().await;
|
let handler = call.lock().await;
|
||||||
|
|
||||||
let queue = handler.queue();
|
let queue = handler.queue();
|
||||||
let current = match queue.current() {
|
let current = queue
|
||||||
Some(channel) => channel,
|
.current()
|
||||||
None => {
|
.ok_or_else(|| anyhow!("Not currently playing"))?;
|
||||||
let text = "Not currently playing";
|
|
||||||
msg.reply(ctx, text).await?;
|
msg.reply(&ctx.http, song_message(None, current.metadata()))
|
||||||
return Err(anyhow!(text).into());
|
.await?;
|
||||||
}
|
|
||||||
};
|
|
||||||
let text = song_message(None, current.metadata());
|
|
||||||
msg.reply(&ctx.http, text).await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -235,18 +221,20 @@ async fn remove(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
|||||||
let index = args.single()?;
|
let index = args.single()?;
|
||||||
|
|
||||||
let queue = handler.queue();
|
let queue = handler.queue();
|
||||||
let text = if let Some(track) = queue.current_queue().get(index) {
|
let current_queue = queue.current_queue();
|
||||||
queue.dequeue(index);
|
|
||||||
let metadata = track.metadata();
|
|
||||||
format!(
|
|
||||||
"Removed track: {} - {} ",
|
|
||||||
metadata.artist.to_owned().unwrap_or_default(),
|
|
||||||
metadata.track.to_owned().unwrap_or_default(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
"No song with that index".into()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let track = current_queue
|
||||||
|
.get(index)
|
||||||
|
.ok_or_else(|| anyhow!("No song with that index"))?;
|
||||||
|
|
||||||
|
queue.dequeue(index);
|
||||||
|
|
||||||
|
let metadata = track.metadata();
|
||||||
|
let text = format!(
|
||||||
|
"Removed track: {} - {} ",
|
||||||
|
metadata.artist.to_owned().unwrap_or_default(),
|
||||||
|
metadata.track.to_owned().unwrap_or_default(),
|
||||||
|
);
|
||||||
msg.reply(&ctx.http, text).await?;
|
msg.reply(&ctx.http, text).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -322,9 +310,9 @@ async fn join_channel(
|
|||||||
let connect_to = match caller_channel {
|
let connect_to = match caller_channel {
|
||||||
Some(channel) => channel,
|
Some(channel) => channel,
|
||||||
None => {
|
None => {
|
||||||
let text = "You must be in a voice channel to use this command";
|
return Err(anyhow!(
|
||||||
msg.reply(ctx, text).await?;
|
"You must be in a voice channel to use this command"
|
||||||
return Err(anyhow!(text));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -335,6 +323,5 @@ async fn join_channel(
|
|||||||
|
|
||||||
async fn load_song(song: &Song, client: &sunk::Client) -> Result<Input> {
|
async fn load_song(song: &Song, client: &sunk::Client) -> Result<Input> {
|
||||||
let url = song.stream_url(&client)?;
|
let url = song.stream_url(&client)?;
|
||||||
println!("{:?}", url);
|
|
||||||
Ok(songbird::ffmpeg(url).await?)
|
Ok(songbird::ffmpeg(url).await?)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user