MP3 Transcoder¶
This module transcodes the users source music into mp3 data that can be streamed via musicdb.lib.stream.icecast.IcecastInterface
.
Therefore it uses the musicdb.lib.stream.gstreamer.GStreamerInterface
class.
A GStreamer Pipeline will be created to transcode m4a, mp3 and flac files into a specific mp3 encoding.
The output of the GStreamer Pipeline gets written into a UNIX Pipe.
The data can then be accessed via GetChunk()
.
GStreamer Pipeline for Transcoding¶
As shown in the graph below, GStreamer is used for the transcoding.
The files get read by the filesrc
element and then be decoded.
The raw audio data gets then be encoded using the lamemp3enc
element.
These mp3 encoded data will then be provided by writing into a UNIX Pipe for further processing.
The encoding is a MPEG v1 Layer III encoding with 320kb/s and Joint Stereo.
The following example shows the bash representation of the pipeline:
gst-launch-1.0 filesrc location=in.m4a ! decodebin ! audioconvert ! lamemp3enc target=1 bitrate=320 cbr=true ! filesink location=out.mp3 file out.mp3 #> out.mp3: MPEG ADTS, layer III, v1, 320 kbps, 44.1 kHz, JntStereo ffpribe out.mp3 #> Duration: 00:03:43.16, start: 0.000000, bitrate: 320 kb/s #> Stream #0:0: Audio: mp3, 44100 Hz, stereo, s16p, 320 kb/s
UNIX Pipe¶
A UNIX Pipe is connected to the fdsink
GStreamer Element.
fdsink
writes into the pipe.
Then MP3Transcoder.GetChunk()
reads some chunks from the mp3 data encoded by the lamemp3enc
Element.
The pipe is accessed non-blocking.
Transcoding¶
Transcoding will be done in a separate thread.
To safely work with the MP3Transcoder
class, you should use the provided context management:
with MP3Transcoder("/tmp/test.flac") as transcoder: # …
MP3Transcoder Class¶
- class musicdb.lib.stream.mp3transcoder.MP3Transcoder(path)[source]¶
- Parameters
path (str/Path) – The absolute path of the audio file that shall be transcoded
Example
with MP3Transcoder("/tmp/test.flac") as transcoder: while True: chunk = transcoder.GetChunk(4096) if len(chunk) == 0: break
- Cancel()[source]¶
This method cancels a currently running transcoding process. If there is no transcoding going on, nothing happens.
The GStreamer object gets set into CANCEL state. The connection to GStreamer stays established!
- GetChunk(size)[source]¶
This method reads a chunk of data that gets provided by the GStreamer
fdsink
element from the GStreamer Pipeline. This element writes into a UNIX Pipe. It tries to readsize
bytes of data.When reading from the UNIX Pipe fails with an
BlockingIOError
, than the state of the current transcoding gets checked. If it isRUNNING
, than the method tries to read from the pipe again after 100ms. Otherwise it is assumed that the process of transcoding is complete.When 0 bytes were read and the state of the transcoding process is not
RUNNING
, than it is also assumed that the process is competed.In all cases, all collected bytes were returned by this method. It may only be less that
size
. When there were less thansize
bytes returned, or even0
, than the process of transcoding can be considered complete.The following diagram shows how this method gets the data from the GStreamer Pipeline via UNIX Pipes:
- Parameters
size (int) – Number of bytes to read
- Returns
A chunk of data as type
bytes
Example
print("\033[1;36mTranscoding %s"%(path)) sinkpath = path + ".mp3" sinkfile = open(sinkpath, "wb") retval = transcoder.Transcode(path) if retval == False: print("\033[1;31mStarting Transcoder failed") return 1 while True: chunk = transcoder.GetChunk(4096) if len(chunk) == 0: break sinkfile.write(chunk) sinkfile.close()
- Transcode()[source]¶
This method starts the transcoding process of a file as thread. After setting the
path
as source for the audio data, a thread gets started that runs the GStreamer Pipeline. Before leaving, the method ensures that the GStreamer Pipeline is running. If an error occursFalse
gets returned, otherwiseTrue
.When calling this method, a previous started transcoding process gets canceled.
- Returns
If an error occurs
False
gets returned, otherwiseTrue
.
Example
transcoder = MP3Transcoder("/tmp/test.flac") retval = transcoder.Transcode() if retval == False: print("[1;31mStarting Transcoder failed!")