Implement Mod_Audio
parent
9c1c320bf3
commit
48c1b572ee
|
@ -53,6 +53,7 @@ module Vrobot4
|
|||
end
|
||||
end
|
||||
|
||||
Thread.abort_on_exception = true
|
||||
Vrobot4.main open("bot.yml")
|
||||
|
||||
## EOF
|
||||
|
|
|
@ -6,29 +6,41 @@ require 'streamio-ffmpeg'
|
|||
|
||||
# @!visibility private
|
||||
class QueueItem
|
||||
def initialize uri
|
||||
attr_accessor :next, :prev
|
||||
attr_reader :time, :ptime, :size, :fname, :descr, :is_stream, :is_file
|
||||
|
||||
def initialize uri, stream = false
|
||||
@is_stream = stream
|
||||
if uri.scheme == "file"
|
||||
@fname = uri.path
|
||||
elsif uri.host and uri.host.include? "youtube.com"
|
||||
@is_file = true
|
||||
elsif uri.host and uri.host.end_with? "youtube.com" or
|
||||
uri.host.end_with? "youtu.be"
|
||||
@fname = get_yt_vid_from uri
|
||||
@is_file = true
|
||||
else
|
||||
@fname = uri.to_s
|
||||
@is_file = false
|
||||
end
|
||||
|
||||
if (mov = FFMPEG::Movie.new(@fname))
|
||||
@descr = uri.to_s
|
||||
|
||||
unless @is_stream
|
||||
if (mov = FFMPEG::Movie.new(@fname)) and mov.valid?
|
||||
@time = mov.duration
|
||||
@size = mov.size
|
||||
@ptime = "%.2i:%.2i" % [@time / 60, @time % 60]
|
||||
else
|
||||
throw ArgumentError, "File is invalid"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_file
|
||||
def file
|
||||
open @fname
|
||||
end
|
||||
|
||||
def cleanup
|
||||
Vrobot4.log :DEBUGV, "cleaning up audio cruft"
|
||||
File.delete @tmpf if @tmpf
|
||||
end
|
||||
|
||||
|
@ -59,45 +71,157 @@ class Mod_Audio < Vrobot4::Module::Module
|
|||
|
||||
def initialize info
|
||||
super
|
||||
register :c_summon, "summon", "Brings the bot to your voice channel."
|
||||
register :c_vanquish, "vanquish", "Kicks the bot from voice.", roles: "o"
|
||||
register :c_play, "play", "Overwrites the queue.", roles: "o"
|
||||
register :c_queue, "queue", "Adds an item to the queue."
|
||||
register :c_join, "voicejoin", "Brings the bot to your voice channel."
|
||||
register :c_quit, "voicequit", "Kicks the bot from voice.", roles: "h"
|
||||
register :c_queue, "queue", "Adds an item to the queue or lists it."
|
||||
register :c_volume, "volume", "Sets the bot's volume."
|
||||
register :c_skip, "skip", "Skips to the next song."
|
||||
register :c_pause, "pause", "Pauses the current song."
|
||||
register :c_play, "play", "Resumes the current song."
|
||||
register :c_rmqueue, "rmqueue", "Removes an item from the queue."
|
||||
# TODO: add stream playing command
|
||||
@queue = []
|
||||
@queue_mtx = Mutex.new
|
||||
@running = false
|
||||
end
|
||||
|
||||
def c_summon m, argv
|
||||
m.serv.voice_join m
|
||||
def c_join m, argv
|
||||
vc = m.user.real.voice_channel
|
||||
raise RuntimeError, "You're not in a voice channel" unless vc
|
||||
m.serv.bot.voice_connect vc
|
||||
end
|
||||
|
||||
def c_vanquish m, argv
|
||||
m.serv.voice_quit m
|
||||
end
|
||||
|
||||
def c_play m, argv
|
||||
@queue.clear
|
||||
push_queue m, argv
|
||||
start_playback m, qi
|
||||
def c_quit m, argv
|
||||
m.serv.voice_quit
|
||||
end
|
||||
|
||||
def c_queue m, argv
|
||||
push_queue m, argv
|
||||
start_playback m, qi unless m.serv.is_playing? m
|
||||
if argv.empty?
|
||||
list_queue m
|
||||
elsif push_queue m, argv and (@queue.size == 1 or not @running)
|
||||
start_playback m, 0
|
||||
end
|
||||
end
|
||||
|
||||
def c_rmqueue m, argv
|
||||
begin
|
||||
@queue_mtx.lock
|
||||
rm_queue @queue[argv.to_i + 1]
|
||||
ensure
|
||||
@queue_mtx.unlock
|
||||
end
|
||||
end
|
||||
|
||||
def c_volume m, argv
|
||||
num = argv.to_f
|
||||
num = num > 1 ? 1 : num < 0.1 ? 0.1 : num
|
||||
m.serv.bot.voice(m.chan.real).volume = num
|
||||
end
|
||||
|
||||
def c_skip m, argv
|
||||
m.serv.bot.voice(m.chan.real).stop_playing
|
||||
end
|
||||
|
||||
def c_pause m, argv
|
||||
m.serv.bot.voice(m.chan.real).pause
|
||||
end
|
||||
|
||||
def c_play m, argv
|
||||
m.serv.bot.voice(m.chan.real).play
|
||||
end
|
||||
|
||||
private
|
||||
def push_queue m, argv
|
||||
m.reply "Queueing '" + uri.to_s + "'..."
|
||||
|
||||
uri = URI.parse argv
|
||||
qi = @queue.push QueueItem.new(uri)
|
||||
|
||||
m.reply "'" + uri.to_s + "' loaded (%i sec, %i bytes)" %
|
||||
[qi.time, qi.size]
|
||||
def list_queue m
|
||||
begin
|
||||
@queue_mtx.lock
|
||||
text = ""
|
||||
i = 1
|
||||
for qi in @queue
|
||||
text << "%i - <%s> (%s" % [i, qi.descr, qi.ptime]
|
||||
text << ", %i bytes" % [qi.size] unless qi.is_stream
|
||||
text << ")\n"
|
||||
i += 1
|
||||
end
|
||||
if text.empty? then m.reply "No items in queue."
|
||||
else m.reply_b text end
|
||||
ensure
|
||||
@queue_mtx.unlock
|
||||
end
|
||||
end
|
||||
|
||||
def start_playback m, qi
|
||||
m.serv.voice_play m, qi.get_file
|
||||
def push_queue m, argv, stream = false
|
||||
uri = URI.parse argv
|
||||
|
||||
m.reply "Queueing <" + uri.to_s + ">..."
|
||||
m.chan.real.start_typing if m.serv.class.type == "Discord"
|
||||
|
||||
begin
|
||||
qi = QueueItem.new(uri, stream)
|
||||
begin
|
||||
@queue_mtx.lock
|
||||
if @queue.any?
|
||||
@queue.last.next = qi
|
||||
qi.prev = @queue.last
|
||||
end
|
||||
@queue.push qi
|
||||
ensure
|
||||
@queue_mtx.unlock
|
||||
end
|
||||
if qi.is_stream
|
||||
m.reply "Stream <" + uri.to_s + "> queued"
|
||||
else
|
||||
m.reply "<" + uri.to_s + "> loaded (%s, %i bytes)" %
|
||||
[qi.ptime, qi.size]
|
||||
end
|
||||
return true
|
||||
rescue
|
||||
p $!
|
||||
m.reply "Couldn't load queue item"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def rm_queue qi
|
||||
@queue.delete qi
|
||||
qi.prev.next = qi.next if qi.prev
|
||||
qi.next.prev = qi.prev if qi.next
|
||||
qi.cleanup
|
||||
end
|
||||
|
||||
def start_playback m, start
|
||||
@running = true
|
||||
|
||||
begin
|
||||
@queue_mtx.lock
|
||||
qi = @queue[start]
|
||||
ensure
|
||||
@queue_mtx.unlock
|
||||
end
|
||||
|
||||
Thread.new do
|
||||
loop do
|
||||
begin
|
||||
if qi.is_file then m.serv.voice_play_io m, qi.file
|
||||
else m.serv.voice_play m, qi.fname end
|
||||
rescue
|
||||
p $!
|
||||
m.reply "Error playing queue item."
|
||||
end
|
||||
|
||||
begin
|
||||
@queue_mtx.lock
|
||||
rm_queue qi
|
||||
ensure
|
||||
@queue_mtx.unlock
|
||||
end
|
||||
|
||||
unless (qi = qi.next)
|
||||
m.reply "End of queue reached."
|
||||
@running = false
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue