add simple mux command
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					target/
 | 
				
			||||||
 | 
					result
 | 
				
			||||||
@@ -20,9 +20,10 @@
 | 
				
			|||||||
          devShells = with pkgs; {
 | 
					          devShells = with pkgs; {
 | 
				
			||||||
            default = mkShell
 | 
					            default = mkShell
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
                buildInputs = [
 | 
					                buildInputs = with gst_all_1; [
 | 
				
			||||||
                  rust-bin.nightly.latest.default
 | 
					                  rust-bin.nightly.latest.default
 | 
				
			||||||
                  rust-analyzer
 | 
					                  rust-analyzer
 | 
				
			||||||
 | 
					                  ffmpeg
 | 
				
			||||||
                ];
 | 
					                ];
 | 
				
			||||||
              };
 | 
					              };
 | 
				
			||||||
            bare = mkShell
 | 
					            bare = mkShell
 | 
				
			||||||
@@ -47,6 +48,9 @@
 | 
				
			|||||||
            nativeBuildInputs = with pkgs; [
 | 
					            nativeBuildInputs = with pkgs; [
 | 
				
			||||||
              rust-bin.nightly.latest.default
 | 
					              rust-bin.nightly.latest.default
 | 
				
			||||||
            ];
 | 
					            ];
 | 
				
			||||||
 | 
					            buildInputs = with pkgs; [
 | 
				
			||||||
 | 
					              ffmpeg
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
            cargoSha256 = "sha256-DhWWUNDpDsao6lOogoM5UfUgrUfEmZvCpY0pxmr4/mI=";
 | 
					            cargoSha256 = "sha256-DhWWUNDpDsao6lOogoM5UfUgrUfEmZvCpY0pxmr4/mI=";
 | 
				
			||||||
          };
 | 
					          };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								general.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								general.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					use serenity::framework::standard::{macros::command, CommandResult};
 | 
				
			||||||
 | 
					use serenity::model::prelude::*;
 | 
				
			||||||
 | 
					use serenity::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[command]
 | 
				
			||||||
 | 
					pub async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
 | 
				
			||||||
 | 
					    msg.reply(ctx, "Pong!").await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/commands/general.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/commands/general.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					use serenity::framework::standard::{macros::command, CommandResult};
 | 
				
			||||||
 | 
					use serenity::model::prelude::*;
 | 
				
			||||||
 | 
					use serenity::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[command]
 | 
				
			||||||
 | 
					pub async fn ping(ctx: &Context, msg: &Message) -> CommandResult {
 | 
				
			||||||
 | 
					    msg.reply(ctx, "Pong!").await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								src/commands/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/commands/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					pub mod general;
 | 
				
			||||||
 | 
					pub mod transcode;
 | 
				
			||||||
							
								
								
									
										71
									
								
								src/commands/transcode.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/commands/transcode.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					use crate::lib::ffmpeg::FfmpegTranscode;
 | 
				
			||||||
 | 
					use serenity::{
 | 
				
			||||||
 | 
					    framework::standard::{macros::command, Args, CommandResult},
 | 
				
			||||||
 | 
					    http::AttachmentType,
 | 
				
			||||||
 | 
					    model::prelude::*,
 | 
				
			||||||
 | 
					    prelude::*,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use std::{fs::remove_file, path::Path, process::ExitStatus};
 | 
				
			||||||
 | 
					use tokio::fs::File;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[command]
 | 
				
			||||||
 | 
					#[aliases("mux")]
 | 
				
			||||||
 | 
					pub async fn remux(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
 | 
				
			||||||
 | 
					    let q: Vec<&str> = args.raw().collect::<Vec<&str>>();
 | 
				
			||||||
 | 
					    if q.len() < 2 || q.len() > 4 {
 | 
				
			||||||
 | 
					        msg.reply(
 | 
				
			||||||
 | 
					            ctx,
 | 
				
			||||||
 | 
					            "Please use the proper syntax: `xxremux <audio> <video> [audio_codec] [video_codec]` or attach something",
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .await?;
 | 
				
			||||||
 | 
					        return Ok(());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut trans = FfmpegTranscode::default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    trans.add_input(q[0]).add_input(q[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if q.len() > 2 {
 | 
				
			||||||
 | 
					        trans.set_acodec(q[2]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if q.len() > 3 {
 | 
				
			||||||
 | 
					        trans.set_vcodec(q[3]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let ext = Path::new(&q[1]).extension().unwrap().to_str().unwrap();
 | 
				
			||||||
 | 
					    let output = format!("/tmp/{}{}.{}", "singh4-", msg.id, ext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    trans
 | 
				
			||||||
 | 
					        .add_flag("shortest")
 | 
				
			||||||
 | 
					        .set_output(&output)
 | 
				
			||||||
 | 
					        .add_arg("map", "0:a:0")
 | 
				
			||||||
 | 
					        .add_arg("map", "1:v:0");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut m = msg.reply_ping(ctx, "Working").await?;
 | 
				
			||||||
 | 
					    let exit_code: ExitStatus = trans.run();
 | 
				
			||||||
 | 
					    let file: File = File::open(&output).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if !exit_code.success() {
 | 
				
			||||||
 | 
					        msg.reply(ctx, "Some error occurred, please check the inputs")
 | 
				
			||||||
 | 
					            .await?;
 | 
				
			||||||
 | 
					    } else if file.metadata().await.unwrap().len() > 8 * 1024 * 1024 {
 | 
				
			||||||
 | 
					        msg.reply(ctx, "Output file larger than 8 MB").await?;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        m.edit(ctx, |m| m.content("Uploading")).await?;
 | 
				
			||||||
 | 
					        msg.channel_id
 | 
				
			||||||
 | 
					            .send_message(ctx, |m| {
 | 
				
			||||||
 | 
					                m.add_file(AttachmentType::File {
 | 
				
			||||||
 | 
					                    file: &file,
 | 
				
			||||||
 | 
					                    filename: format!("{}.{}", msg.id, ext),
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					                .content(msg.author.mention())
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .await?;
 | 
				
			||||||
 | 
					        m.delete(ctx).await?;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    remove_file(output)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										84
									
								
								src/lib/ffmpeg.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/lib/ffmpeg.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					use std::process::{Command, ExitStatus};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Helper lib for running ffmpeg using std::process::Command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn sanitize_arg<V: Into<String>>(value: V) -> String {
 | 
				
			||||||
 | 
					    let v: String = value.into();
 | 
				
			||||||
 | 
					    if v.starts_with('-') {
 | 
				
			||||||
 | 
					        v
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        format!("-{}", v)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone, Debug)]
 | 
				
			||||||
 | 
					pub struct FfmpegTranscode {
 | 
				
			||||||
 | 
					    args: Vec<String>,
 | 
				
			||||||
 | 
					    out: String,
 | 
				
			||||||
 | 
					    acodec: String,
 | 
				
			||||||
 | 
					    vcodec: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Default for FfmpegTranscode {
 | 
				
			||||||
 | 
					    fn default() -> Self {
 | 
				
			||||||
 | 
					        FfmpegTranscode {
 | 
				
			||||||
 | 
					            args: vec![],
 | 
				
			||||||
 | 
					            out: String::from("/tmp/ffmpeg"),
 | 
				
			||||||
 | 
					            acodec: String::from("copy"),
 | 
				
			||||||
 | 
					            vcodec: String::from("copy"),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl FfmpegTranscode {
 | 
				
			||||||
 | 
					    pub fn add_flag<V: Into<String>>(&mut self, value: V) -> &mut Self {
 | 
				
			||||||
 | 
					        self.args.push(sanitize_arg(value));
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn add_flags<T: Into<String>, V: IntoIterator<Item = T>>(&mut self, value: V) -> &mut Self {
 | 
				
			||||||
 | 
					        for v in value {
 | 
				
			||||||
 | 
					            self.add_flag(v);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn add_arg<K: Into<String>, V: ToString>(&mut self, key: K, value: V) -> &mut Self {
 | 
				
			||||||
 | 
					        self.args.push(sanitize_arg(key));
 | 
				
			||||||
 | 
					        self.args.push(value.to_string());
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn add_input<V: ToString>(&mut self, input: V) -> &mut Self {
 | 
				
			||||||
 | 
					        self.add_arg('i', input)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_output<V: ToString>(&mut self, output: V) -> &mut Self {
 | 
				
			||||||
 | 
					        self.out = output.to_string();
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_acodec<V: ToString>(&mut self, acodec: V) -> &mut Self {
 | 
				
			||||||
 | 
					        self.acodec = acodec.to_string();
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_vcodec<V: ToString>(&mut self, vcodec: V) -> &mut Self {
 | 
				
			||||||
 | 
					        self.vcodec = vcodec.to_string();
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn add_map(&mut self, inp: i32, s: char, out: i32) -> &mut Self {
 | 
				
			||||||
 | 
					        self.add_arg("map", format!("{}:{}:{}", inp, s, out))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn run(&self) -> ExitStatus {
 | 
				
			||||||
 | 
					        Command::new("ffmpeg")
 | 
				
			||||||
 | 
					            .args(&self.args)
 | 
				
			||||||
 | 
					            .args(vec!["-c:a", &self.acodec])
 | 
				
			||||||
 | 
					            .args(vec!["-c:v", &self.vcodec])
 | 
				
			||||||
 | 
					            .arg(&self.out)
 | 
				
			||||||
 | 
					            .status()
 | 
				
			||||||
 | 
					            .expect("FFmpeg failed to run")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/lib/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/lib/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					pub mod ffmpeg;
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,11 +1,15 @@
 | 
				
			|||||||
 | 
					mod commands;
 | 
				
			||||||
mod handler;
 | 
					mod handler;
 | 
				
			||||||
 | 
					mod lib;
 | 
				
			||||||
 | 
					use commands::general::*;
 | 
				
			||||||
 | 
					use commands::transcode::*;
 | 
				
			||||||
use handler::Handler;
 | 
					use handler::Handler;
 | 
				
			||||||
use serenity::{
 | 
					use serenity::{
 | 
				
			||||||
    client::bridge::gateway::ShardManager,
 | 
					    client::bridge::gateway::ShardManager,
 | 
				
			||||||
    framework::{
 | 
					    framework::{
 | 
				
			||||||
        standard::{
 | 
					        standard::{
 | 
				
			||||||
            help_commands,
 | 
					            help_commands,
 | 
				
			||||||
            macros::help,
 | 
					            macros::{group, help},
 | 
				
			||||||
            Args, CommandGroup, CommandResult, HelpOptions,
 | 
					            Args, CommandGroup, CommandResult, HelpOptions,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        StandardFramework,
 | 
					        StandardFramework,
 | 
				
			||||||
@@ -22,6 +26,14 @@ impl TypeMapKey for ShardManagerContainer {
 | 
				
			|||||||
    type Value = Arc<Mutex<ShardManager>>;
 | 
					    type Value = Arc<Mutex<ShardManager>>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[group]
 | 
				
			||||||
 | 
					#[commands(remux)]
 | 
				
			||||||
 | 
					struct Transcode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[group]
 | 
				
			||||||
 | 
					#[commands(ping)]
 | 
				
			||||||
 | 
					struct General;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[help]
 | 
					#[help]
 | 
				
			||||||
#[max_levenshtein_distance(2)]
 | 
					#[max_levenshtein_distance(2)]
 | 
				
			||||||
#[indention_prefix = "+"]
 | 
					#[indention_prefix = "+"]
 | 
				
			||||||
@@ -56,8 +68,10 @@ async fn main() {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let framework = StandardFramework::new()
 | 
					    let framework = StandardFramework::new()
 | 
				
			||||||
        .configure(|c| c.owners(owners).prefix(","))
 | 
					        .configure(|c| c.owners(owners).prefix("xx"))
 | 
				
			||||||
        .help(&MY_HELP);
 | 
					        .help(&MY_HELP)
 | 
				
			||||||
 | 
					        .group(&GENERAL_GROUP)
 | 
				
			||||||
 | 
					        .group(&TRANSCODE_GROUP);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut client = Client::builder(&token)
 | 
					    let mut client = Client::builder(&token)
 | 
				
			||||||
        .framework(framework)
 | 
					        .framework(framework)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user