Format conversion¶
No matter in which format files were indexed, it is possible to convert tracks
to serve them in different formats. For this you are going to need ffmpeg
installed in your system.
If you have fmpeg compiled but not installed, you can give Shiva the path
to the binary in a setting, in this format:
FFMPEG_PATH = '/usr/bin/ffmpeg'
You will notice that track objects contain a files attribute:
{
"id": 510,
"uri": "/track/510",
"files": {
"audio/mp3": "http://localhost:8080/nofx-pump_up_the_valuum/04. Dinosaurs Will Die.mp3",
"audio/ogg": "/track/510/convert?mimetype=audio%2Fogg"
}
}
In that attribute you will find a list of all the supported formats. That list
is generated from the MIMETYPES setting (see The MIMETYPES config). Just
follow the link of the format you need and Shiva will convert it if necessary
and serve it for you. As a client, that’s all you care about.
But you may have noticed that the URI for the audio/ogg format goes through
Shiva. This is because the file has not been yet converted, once you call that
URI, Shiva will convert the file on the fly, cache it and redirect to the file.
The next time the same track is requested, if the file exists it will be served
through the file server instead of Shiva:
{
"id": 510,
"uri": "/track/510",
"files": {
"audio/mp3": "http://localhost:8080/nofx-pump_up_the_valuum/04. Dinosaurs Will Die.mp3",
"audio/ogg": "http://localhost:8080/nofx-pump_up_the_valuum/04. Dinosaurs Will Die.ogg"
}
}
It’s completely transparent for the client. If you want an OGG file, you just follow the “audio/ogg” URI blindly, and you will get your file. The first time will take a little longer, though.
Absolute paths¶
If you need absolute paths for your /convert URIs, just set the
SERVER_URI setting in your local config, it will be prepended to all the
URIs:
SERVER_URI = 'http://127.0.0.1:9002'
Example output:
{
"files": {
"audio/mp3": "http://127.0.0.1:8001/flip-keep_rockin/flip-10-away_from_the_sun.mp3",
"audio/ogg": "http://127.0.0.1:9002/track/1/convert?mimetype=audio%2Fogg"
},
"album": {
"id": 1,
"uri": "http://127.0.0.1:9002/album/1"
},
"length": 168,
"number": 10,
"title": "Away From The Sun",
"slug": "away-from-the-sun",
"artist": {
"id": 1,
"uri": "http://127.0.0.1:9002/artist/1"
},
"bitrate": 192000,
"id": 1,
"uri": "http://127.0.0.1:9002/track/1"
}
Remember to leave out trailing slashes.
Your converter sucks¶
So, you don’t want to use ffmpeg, or you want to call it with different
parameters, or chache files differently. That’s ok, I won’t take it personally.
To overwrite the Converter class to use, just define it in your config:
from shiva.myconverter import MyBetterConverter
CONVERTER_CLASS = MyBetterConverter
One option is to extend shiva.converter.Converter and overwrite the methods
that offend you.
The other option is to write a completely new Converter class. If you do so, make sure to have at least the following 3 methods:
__init__(Track track, (str, MimeType) mimetype): Constructor accepting a path to a file and a mimetype, which could be a string in the form of ‘type/subtype’, or a MimeType instance.convert(): Converts to a different format.get_uri(): Retrieves the URI to the converted file.
The shiva.resources.ConvertResource class makes use of them.
The MimeType class¶
All mimetypes are represented by a shiva.media.MimeType class. The
constructor receives the following parameters:
type: Would beaudioinaudio/ogg.subtype: Would beogginaudio/ogg.extension: The extension that converted files should have.acodecand/orvcodec: The codecs used byConverter.convert(). Find out the available codecs running:
$ ffmpeg -codecs
The MIMETYPES config¶
You will see in your config file:
MIMETYPES = (
MimeType(type='audio', subtype='mp3', extension='mp3',
acodec='libmp3lame'),
MimeType(type='audio', subtype='ogg', extension='ogg',
acodec='libvorbis'),
)
Keep in mind that an invalid MimeType in this config will raise an
InvalidMimeTypeError exception.