m3u8
m3u8 provides easy generation and parsing of m3u8 playlists defined in the HTTP Live Streaming (HLS) Internet Draft published by Apple.
- The library completely implements version 20 of the HLS Internet Draft.
- Provides parsing of an m3u8 playlist into an object model from any File, StringIO, or string.
- Provides ability to write playlist to a File or StringIO or expose as string via to_s.
- Distinction between a master and media playlist is handled automatically (single Playlist class).
- Optionally, the library can automatically generate the audio/video codecs string used in the CODEC attribute based on specified H.264, AAC, or MP3 options (such as Profile/Level).
Installation
Add this line to your application's Gemfile:
gem 'm3u8'
And then execute:
$ bundle
Or install it yourself as:
$ gem install m3u8
Usage (creating playlists)
Create a master playlist and add child playlists for adaptive bitrate streaming:
require 'm3u8'
playlist = M3u8::Playlist.new
Create a new playlist item with options:
options = { width: 1920, height: 1080, profile: 'high', level: 4.1,
audio_codec: 'aac-lc', bandwidth: 540, uri: 'test.url' }
item = M3u8::PlaylistItem.new(options)
playlist.items << item
Add alternate audio, camera angles, closed captions and subtitles by creating MediaItem instances and adding them to the Playlist:
hash = { type: 'AUDIO', group_id: 'audio-lo', language: 'fre',
assoc_language: 'spoken', name: 'Francais', autoselect: true,
default: false, forced: true, uri: 'frelo/prog_index.m3u8' }
item = M3u8::MediaItem.new(hash)
playlist.items << item
Create a standard playlist and add MPEG-TS segments via SegmentItem. You can also specify options for this type of playlist, however these options are ignored if playlist becomes a master playlist (anything but segments added):
options = { version: 1, cache: false, target: 12, sequence: 1 }
playlist = M3u8::Playlist.new(options)
item = M3u8::SegmentItem.new(duration: 11, segment: 'test.ts')
playlist.items << item
You can pass an IO object to the write method:
require 'tempfile'
file = Tempfile.new('test')
playlist.write(file)
You can also access the playlist as a string:
playlist.to_s
M3u8::Writer is the class that handles generating the playlist output.
Alternatively you can set codecs rather than having it generated automatically:
options = { width: 1920, height: 1080, codecs: 'avc1.66.30,mp4a.40.2',
bandwidth: 540, uri: 'test.url' }
item = M3u8::PlaylistItem.new(options)
Usage (parsing playlists)
file = File.open 'spec/fixtures/master.m3u8'
playlist = M3u8::Playlist.read(file)
playlist.master?
# => true
Access items in playlist:
playlist.items.first
# => #<M3u8::PlaylistItem:0x007fa569bc7698 @program_id="1", @resolution="1920x1080",
# @codecs="avc1.640028,mp4a.40.2", @bandwidth="5042000",
# @playlist="hls/1080-7mbps/1080-7mbps.m3u8">
Create a new playlist item with options:
options = { width: 1920, height: 1080, profile: 'high', level: 4.1,
audio_codec: 'aac-lc', bandwidth: 540, uri: 'test.url' }
item = M3u8::PlaylistItem.new(options)
#add it to the top of the playlist
playlist.items.unshift(item)
M3u8::Reader is the class handles parsing if you want more control over the process.
Usage (misc)
Generate the codec string based on audio and video codec options without dealing a playlist instance:
options = { profile: 'baseline', level: 3.0, audio_codec: 'aac-lc' }
codecs = M3u8::Playlist.codecs(options)
# => "avc1.66.30,mp4a.40.2"
- Values for audio_codec (codec name): aac-lc, he-aac, mp3
- Values for profile (H.264 Profile): baseline, main, high.
- Values for level (H.264 Level): 3.0, 3.1, 4.0, 4.1.
Not all Levels and Profiles can be combined and validation is not currently implemented, consult H.264 documentation for further details.
Roadmap
- Implement validation of all tags, attributes, and values per HLS I-D.
- Perhaps support for different versions of HLS I-D, defaulting to latest.
Contributing
- Fork it ( https://github.com/sethdeckard/m3u8/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Run the specs, make sure they pass and that new features are covered. Code coverage should be 100%.
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
License
MIT License - See LICENSE.txt for details.