Class: Rubycord::Voice::Encoder
- Inherits:
-
Object
- Object
- Rubycord::Voice::Encoder
- Defined in:
- lib/rubycord/voice/encoder.rb
Overview
This class conveniently abstracts opus and ffmpeg/avconv, for easy implementation of voice sending. It's not very useful for most users, but I guess it can be useful sometimes.
Constant Summary collapse
- OPUS_SILENCE =
One frame of complete silence Opus encoded
-
[0xF8, 0xFF, 0xFE].pack("C*").freeze
Instance Attribute Summary collapse
-
#filter_volume ⇒ Integer
The volume used as a filter to ffmpeg/avconv.
-
#use_avconv ⇒ true, false
Whether or not avconv should be used instead of ffmpeg.
Instance Method Summary collapse
-
#adjust_volume(buf, mult) ⇒ String
Adjusts the volume of a given buffer of s16le PCM data.
-
#bitrate=(value) ⇒ Object
Set the opus encoding bitrate.
-
#encode(buffer) ⇒ String
Encodes the given buffer using opus.
-
#encode_file(file, options = "") ⇒ IO
Encodes a given file (or rather, decodes it) using ffmpeg.
-
#encode_io(io, options = "") ⇒ IO
Encodes an arbitrary IO audio stream using ffmpeg.
-
#initialize ⇒ Encoder
constructor
Create a new encoder.
Constructor Details
#initialize ⇒ Encoder
Create a new encoder
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/rubycord/voice/encoder.rb', line 24 def initialize sample_rate = 48_000 frame_size = 960 channels = 2 @filter_volume = 1 raise LoadError, "Opus unavailable - voice not supported! Please install opus for voice support to work." unless OPUS_AVAILABLE @opus = Opus::Encoder.new(sample_rate, frame_size, channels) end |
Instance Attribute Details
#filter_volume ⇒ Integer
Returns the volume used as a filter to ffmpeg/avconv.
21 22 23 |
# File 'lib/rubycord/voice/encoder.rb', line 21 def filter_volume @filter_volume end |
#use_avconv ⇒ true, false
Whether or not avconv should be used instead of ffmpeg. If possible, it is recommended to use ffmpeg instead, as it is better supported.
17 18 19 |
# File 'lib/rubycord/voice/encoder.rb', line 17 def use_avconv @use_avconv end |
Instance Method Details
#adjust_volume(buf, mult) ⇒ String
Adjusts the volume of a given buffer of s16le PCM data.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rubycord/voice/encoder.rb', line 55 def adjust_volume(buf, mult) # We don't need to adjust anything if the buf is nil so just return in that case return unless buf # buf is s16le so use 's<' for signed, 16 bit, LE result = buf.unpack("s<*").map do |sample| sample *= mult # clamp to s16 range sample.clamp(-32_768, 32_767) end # After modification, make it s16le again result.pack("s<*") end |
#bitrate=(value) ⇒ Object
Set the opus encoding bitrate
37 38 39 |
# File 'lib/rubycord/voice/encoder.rb', line 37 def bitrate=(value) @opus.bitrate = value end |
#encode(buffer) ⇒ String
Encodes the given buffer using opus.
44 45 46 |
# File 'lib/rubycord/voice/encoder.rb', line 44 def encode(buffer) @opus.encode(buffer, 1920) end |
#encode_file(file, options = "") ⇒ IO
Encodes a given file (or rather, decodes it) using ffmpeg. This accepts pretty much any format, even videos with an audio track. For a list of supported formats, see https://ffmpeg.org/general.html#Audio-Codecs. It even accepts URLs, though encoding them is pretty slow - I recommend to make a stream of it and then use #encode_io instead.
77 78 79 80 |
# File 'lib/rubycord/voice/encoder.rb', line 77 def encode_file(file, = "") command = ffmpeg_command(input: file, options: ) IO.popen(command) end |
#encode_io(io, options = "") ⇒ IO
Encodes an arbitrary IO audio stream using ffmpeg. Accepts pretty much any media format, even videos with audio tracks. For a list of supported audio formats, see https://ffmpeg.org/general.html#Audio-Codecs.
87 88 89 90 |
# File 'lib/rubycord/voice/encoder.rb', line 87 def encode_io(io, = "") command = ffmpeg_command(options: ) IO.popen(command, in: io) end |