ITQF7AQWZNN733JQHK3PHYDWDGM4JJZVFBLB7F7XPS56PMHCKTMQC AYSPIRRQNBESKXOVILHY4QEIZA37AOFFT5KY75GKZJIPUXD62UIQC LB4HIYWKTVYQPH77VAQCFOXNO7JD72SMXTK2U6G7UC2MDQM6VHPAC HMJFS6WWD2JJZB57HBXRHYS2A2N25YDDAJ443KRMT6K3ALHIBRVQC FEHWT3MOW3STJXNBQWXSY6ZDSJIJWVU6EWCXA6KARH7DCYFNM5NQC P35HCXDOT4NKKPTM6OMKEVKBLB3VLEODS7LNKRG7777RLOFDGU2AC B22T6OTOYMTCUQJGC4DVNB2FNKIYQHLU3I7H2OBWTNLX5WT2Y5RQC WWOXTYSKCYOBP6H7OQNLZJ22O6WVWCHQNJTHBRQ3ZEJH2KSQF3UAC MGOB3WXKVDFPE5PPKWC4EEST2CR4NQ7B2FASVYHO5JNNGXC5NNPAC let* s = D.Audio_stream.Ffmpeg.of_file "./bite2.mp3" in
let* s = D.Audio_stream.Ffmpeg.create "./bite2.mp3" inmatch s with| Ok audio_stream ->D.Client.play_audio_stream ~guild_id audio_stream client| _ -> Lwt.return_unit)| Some ("play", "allstar") -> (let guild_id = Option.get_exn guild_id inlet* s = D.Audio_stream.Ffmpeg.create "./allstar.mp3" in
| Some ("play", query) -> (let guild_id = Option.get_exn guild_id inlet* tracks = Ytdl.query query inmatch tracks with| Ok [] | Error _ ->let msg = Msg.fmt "⚠️ No track found for query: '%s'" query inD.Client.send_message channel_id msg client| Ok (track :: _) -> (let* s = D.Audio_stream.Ffmpeg.create track.url inmatch s with| Ok audio_stream ->let* () =D.Client.play_audio_stream ~guild_id audio_stream clientinlet msg =Msg.fmt "🎵 @{<b>Now playing:@} '%s'\n%s" track.titletrack.thumbnailinD.Client.send_message channel_id msg client| Error e ->client|> D.Client.send_message channel_id(Msg.fmt "⚠️ Couldn't play track: '%s'\nReason: %a"track.title D.Error.pp e)))| Some ("pause", _) ->let _guild_id = Option.get_exn guild_id inLwt.return_unit
open Containersopen Lwt.Infixmodule L = (val Relog.logger ~namespace:__MODULE__ ())type track = { title : string; url : string; thumbnail : string }let args =[ "--default-search"; "ytsearch1:"; "-f"; "webm[abr>0]/bestaudio/best"; "-j" ]let query q =let cmd = "youtube-dl" inlet playlist = String.find ~sub:"list=" q <> -1 inlet args = args @ [ q ] inlet args = if playlist then "--flat-playlist" :: args else args inlet cmd_str = cmd :: args |> List.to_string ~sep:" " Fun.id inL.info (fun m -> m "running cmd: %s" cmd_str);Lwt_process.with_process_full("", Array.of_list @@ cmd :: args)(fun proc ->let _logs () = Lwt_io.read proc#stderr inL.info (fun m -> m "youtube-dl running with pid=%d" proc#pid);(Lwt_io.read_line proc#stdout |> Lwt_result.catch >|= function| Error End_of_file -> Ok []| Error exn -> Discord.Error.exn exn| Ok track ->let info = Yojson.Safe.from_string track inlet title = Yojson.Safe.Util.(member "title" info |> to_string) inlet url = Yojson.Safe.Util.(member "url" info |> to_string) inlet thumbnail =Yojson.Safe.Util.(member "thumbnail" info |> to_string)inOk [ { title; url; thumbnail } ])>>= fun res ->proc#close >|= fun _ -> res)
"@opam/ppx_bitstring@opam:4.1.0@ded0b52e": {"id": "@opam/ppx_bitstring@opam:4.1.0@ded0b52e","name": "@opam/ppx_bitstring","version": "opam:4.1.0","source": {"type": "install","source": ["archive:https://opam.ocaml.org/cache/md5/8a/8ae6f04eaa29481c6830ee3be5cba755#md5:8ae6f04eaa29481c6830ee3be5cba755","archive:https://github.com/xguerin/bitstring/archive/v4.1.0.tar.gz#md5:8ae6f04eaa29481c6830ee3be5cba755"],"opam": {"name": "ppx_bitstring","version": "4.1.0","path": "esy.lock/opam/ppx_bitstring.4.1.0"}},"overrides": [],"dependencies": ["ocaml@4.11.2000@d41d8cd9", "@opam/ppxlib@opam:0.22.0@d2d2223a","@opam/dune@opam:2.8.4@1490e2a1","@opam/bitstring@opam:4.1.0@1d9e964d","@esy-ocaml/substs@0.0.1@d41d8cd9"],"devDependencies": ["ocaml@4.11.2000@d41d8cd9", "@opam/ppxlib@opam:0.22.0@d2d2223a","@opam/dune@opam:2.8.4@1490e2a1","@opam/bitstring@opam:4.1.0@1d9e964d"]},
"archive:https://opam.ocaml.org/cache/sha256/ce/cee8371e7048e24c90e916c373ef6f3aba6f474d8a5fcf507ab6650fd8575eeb#sha256:cee8371e7048e24c90e916c373ef6f3aba6f474d8a5fcf507ab6650fd8575eeb","archive:https://github.com/ocaml/ocaml-lsp/releases/download/1.4.1/jsonrpc-1.4.1.tbz#sha256:cee8371e7048e24c90e916c373ef6f3aba6f474d8a5fcf507ab6650fd8575eeb"
"archive:https://opam.ocaml.org/cache/md5/2c/2c19731536a4f62923554c1947c39211#md5:2c19731536a4f62923554c1947c39211","archive:https://github.com/ocaml/ocaml-lsp/releases/download/1.5.0/jsonrpc-1.5.0.tbz#md5:2c19731536a4f62923554c1947c39211"
"archive:https://opam.ocaml.org/cache/sha256/9e/9e2e6fc799c93ce1f2c7181645eafa37f64e43ace062b69218e1c29ac459937d#sha256:9e2e6fc799c93ce1f2c7181645eafa37f64e43ace062b69218e1c29ac459937d","archive:https://github.com/ocaml/merlin/releases/download/v4.1-411/merlin-v4.1-411.tbz#sha256:9e2e6fc799c93ce1f2c7181645eafa37f64e43ace062b69218e1c29ac459937d"
"archive:https://opam.ocaml.org/cache/sha256/fb/fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d#sha256:fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d","archive:https://github.com/ocaml/merlin/releases/download/v4.1-412/merlin-v4.1-412.tbz#sha256:fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d"
"@opam/bitstring@opam:4.1.0@1d9e964d": {"id": "@opam/bitstring@opam:4.1.0@1d9e964d","name": "@opam/bitstring","version": "opam:4.1.0","source": {"type": "install","source": ["archive:https://opam.ocaml.org/cache/md5/8a/8ae6f04eaa29481c6830ee3be5cba755#md5:8ae6f04eaa29481c6830ee3be5cba755","archive:https://github.com/xguerin/bitstring/archive/v4.1.0.tar.gz#md5:8ae6f04eaa29481c6830ee3be5cba755"],"opam": {"name": "bitstring","version": "4.1.0","path": "esy.lock/opam/bitstring.4.1.0"}},"overrides": [],"dependencies": ["ocaml@4.11.2000@d41d8cd9", "@opam/stdlib-shims@opam:0.3.0@0d088929","@opam/dune@opam:2.8.4@1490e2a1", "@esy-ocaml/substs@0.0.1@d41d8cd9"],"devDependencies": ["ocaml@4.11.2000@d41d8cd9", "@opam/stdlib-shims@opam:0.3.0@0d088929","@opam/dune@opam:2.8.4@1490e2a1"]},
opam-version: "2.0"synopsis: "Bitstrings and bitstring matching for OCaml"description: """The ocaml-bitstring project adds Erlang-style bitstrings and matching over bitstrings as a syntax extension and library for OCaml.You can use this module to both parse and generate binary formats, files and protocols.Bitstring handling is added as primitives to the language, making it exceptionally simple to use and very powerful."""maintainer: ["Xavier R. Guérin <github@applepine.org>"]authors: ["Richard W.M. Jones" "Xavier R. Guérin"]license: "LGPL-2.0-or-later"homepage: "https://github.com/xguerin/bitstring"bug-reports: "https://github.com/xguerin/bitstring/issues"depends: ["dune" {>= "2.5"}"ocaml" {>= "4.04.1"}"stdlib-shims" {>= "0.1.0"}]build: [["dune" "subst"] {pinned}["dune""build""-p"name"-j"jobs"@install""@runtest" {with-test}"@doc" {with-doc}]]dev-repo: "git+https://github.com/xguerin/bitstring.git"url {src: "https://github.com/xguerin/bitstring/archive/v4.1.0.tar.gz"checksum: "md5=8ae6f04eaa29481c6830ee3be5cba755"}
opam-version: "2.0"synopsis: "Bitstrings and bitstring matching for OCaml - PPX extension"description: """The ocaml-bitstring project adds Erlang-style bitstrings and matching over bitstrings as a syntax extension and library for OCaml.You can use this module to both parse and generate binary formats, files and protocols.Bitstring handling is added as primitives to the language, making it exceptionally simple to use and very powerful."""maintainer: ["Xavier R. Guérin <github@applepine.org>"]authors: ["Richard W.M. Jones" "Xavier R. Guérin"]license: "LGPL-2.0-or-later"homepage: "https://github.com/xguerin/bitstring"bug-reports: "https://github.com/xguerin/bitstring/issues"depends: ["dune" {>= "2.5"}"ocaml" {>= "4.04.1"}"bitstring" {>= "4.0.0"}"ocaml" {with-test & >= "4.08.0"}"ppxlib" {>= "0.18.0"}"ounit" {with-test}]build: [["dune" "subst"] {pinned}["dune""build""-p"name"-j"jobs"@install""@runtest" {with-test}"@doc" {with-doc}]]dev-repo: "git+https://github.com/xguerin/bitstring.git"url {src: "https://github.com/xguerin/bitstring/archive/v4.1.0.tar.gz"checksum: "md5=8ae6f04eaa29481c6830ee3be5cba755"}
"sha256=9e2e6fc799c93ce1f2c7181645eafa37f64e43ace062b69218e1c29ac459937d""sha512=6a2e2503d81b22b0cc292ca6853231e59c42a216acec0cb540d03791d201fe83641a3502e62660668ad5d30405698e2429efe072cfd38dc30229024267f7c0b8"
"sha256=fb4caede73bdb8393bd60e31792af74b901ae2d319ac2f2a2252c694d2069d8d""sha512=ec301e0f97e11c1c331478030372d373d381a0ddbb7f72c83f7baa4c2c6d4f26094c3398f56bcf3d40c1242044391369fd06e8cd2ccfe1f5d78467eb3e9d33be"
"sha256=cee8371e7048e24c90e916c373ef6f3aba6f474d8a5fcf507ab6650fd8575eeb""sha512=150ebf71d3484d3beec1a145877cf30d84581bd072dd20159e878ed07cc4fc647b019b98bb0c9fede839b87f7bd13de4a64b534c0760a2ec57d0e4a4deac6f0f"
"md5=2c19731536a4f62923554c1947c39211""sha512=9bc252e2564fe6c9017b5ee1b2c4ddebf73c4be4b2a3d48f1d61b6ec1910a2cb9f4fa4952a7a6d89482c28ddbad8e0d9c34c206a1b2fe42bb2c3a7156aa953e9"
play frame >>= fun ok ->if ok then exhaust ~i:(i + 1) pelse if i = 0 then failwith "need to send at least 1 frame"else Lwt.return (`Yield i)
play (i + 1) frame >>= fun ok ->let i = i + 1 inif ok then exhaust ~i p else Lwt.return (`Yield i)
Encoder.create ~samplerate:Rtp._SAMPLE_RATE ~channels:`stereo~application:`Audio ()>>= (fun enc ->let shared =CTL.[Set_signal `Music;Set_bitrate `Max;Set_complexity 10;Set_packet_loss_perc 5;Set_complexity 10;Set_inband_FEC true;Set_DTX false;]inlet ctls =match frametype with| `s16 -> CTL.(Set_LSB_depth 16) :: shared| `f32 -> CTL.(Set_LSB_depth 24) :: sharedinset_ctls ~l:ctls enc)|> Result.map_err (fun e ->`Msg (Printf.sprintf "opus error: %s" (Opus.Error.to_string e)))
Opus.(Encoder.create ~samplerate:Rtp._SAMPLE_RATE ~channels:`stereo~application:`Audio ()>>= fun enc ->let shared =CTL.[Set_signal `Music;Set_bitrate `Max;Set_complexity 10;Set_packet_loss_perc 5;Set_inband_FEC true;Set_DTX false;]inlet ctls =match frametype with| `s16 -> CTL.(Set_LSB_depth 16) :: shared| `f32 -> CTL.(Set_LSB_depth 24) :: sharedinset_ctls ~l:ctls enc)|> function| Error e -> Error.msgf "opus error: %a" Opus.Error.pp e| Ok v -> Ok v
let curr = ref 0 inlet play frame =if !curr < burst then (Voice.start_speaking voice >>= fun () ->Voice.send_rtp voice frame >|= fun () ->incr curr;true)else (curr := 0;Lwt.return false)
let play i frame =Voice.start_speaking voice >>= fun () ->Voice.send_rtp voice frame >|= fun () -> i < burst