Skip to content
/ m3u8 Public
forked from sethdeckard/m3u8

Generate and parse m3u8 playlists for HTTP Live Streaming (HLS) in Ruby.

License

Notifications You must be signed in to change notification settings

Spuul/m3u8

 
 

Repository files navigation

Gem Version Build Status Coverage Status Code Climate Dependency Status security

m3u8

m3u8 provides generation and parsing of m3u8 playlists used the HTTP Live Streaming (HLS) specification created by Apple. This is useful if you wish to generate m3u8 playlists on the fly in your web application (to integrate authentication, do something custom, etc) while of course serving up the actual MPEG transport stream files (.ts) from a CDN. You could also use m3u8 to generate playlist files as part of an encoding pipeline. You can also parse existing playlists, add content to them and generate a new output.

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)

Just get the codec string for custom use:

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

Possible values for profile (H.264 Profile): baseline, main, high.

Possible values for level (H.264 Level): 3.0, 3.1, 4.0, 4.1.

Not all Levels and Profiles can be combined, consult H.264 documentation

Parsing Usage

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.

Features

  • Distinction between segment and master playlists is handled automatically (no need to use a different class).
  • Automatically generates the audio/video codec string based on names and options you are familiar with.
  • Provides validation of input when adding playlists or segments.
  • Allows all options to be configured on a playlist (caching, version, etc.)
  • Can write playlist to an IO object (StringIO/File, etc) or access string via to_s.
  • Can read playlists into a model (Playlist and Items) from an IO object.
  • Any tag or attribute supported by the object model is supported both parsing and generation of m3u8 playlists.
  • Supports I-frames (Intra frames) and byte ranges in Segments.
  • Supports subtitles, closed captions, alternate audio and video, and comments.
  • Supports session data in master playlists.
  • Supports keys for encrypted media segments (EXT-X-KEY, EXT-SESSION-KEY).

HLS Spec Status (version 17)

Implemented:

  • EXTM3U
  • EXT-X-VERSION
  • EXTINF
  • EXT-X-BYTERANGE
  • EXT-X-DISCONTINUITY
  • EXT-X-KEY
  • EXT-X-MAP
  • EXT-X-PROGRAM-DATE-TIME
  • EXT-X-TARGETDURATION
  • EXT-X-MEDIA-SEQUENCE
  • EXT-X-ENDLIST
  • EXT-X-PLAYLIST-TYPE
  • EXT-X-I-FRAMES-ONLY
  • EXT-X-MEDIA
  • EXT-X-STREAM-INF
  • EXT-X-I-FRAME-STREAM-INF
  • EXT-X-SESSION-DATA
  • EXT-X-SESSION-KEY

TODO:

  • EXT-X-DISCONTINUITY-SEQUENCE
  • EXT-X-INDEPENDENT-SEGMENTS
  • EXT-X-START

Roadmap

  • Add the last remaining tags for latest version of the spec.
  • Validation of all attributes and their values to match the rules defined in the spec.
  • Support for different versions of spec, defaulting to latest.

Contributing

  1. Fork it ( https://github.com/sethdeckard/m3u8/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Run the specs, make sure they pass and that new features are covered. Code coverage should be 100%.
  4. Commit your changes (git commit -am 'Add some feature')
  5. Push to the branch (git push origin my-new-feature)
  6. Create a new Pull Request

About

Generate and parse m3u8 playlists for HTTP Live Streaming (HLS) in Ruby.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 100.0%