All Projects → globocom → M3u8

globocom / M3u8

Licence: other
Python m3u8 Parser for HTTP Live Streaming (HLS) Transmissions

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to M3u8

M3u8parser
A light weight M3U8 parser. Support X-Key & X-Session-Key.
Stars: ✭ 187 (-82.42%)
Mutual labels:  m3u8, parser, hls
hls m3u8
HLS(RFC8216) m3u8 parser/generator
Stars: ✭ 40 (-96.24%)
Mutual labels:  hls, m3u8
p2p-cdn-sdk-android
Free p2p cdn android github sdk to reduce video streaming costs of live and on demand video using webrtc by upto 90% and improve scalability by 6x - 🚀 Vadootv 🚀
Stars: ✭ 39 (-96.33%)
Mutual labels:  hls, m3u8
JT1078Gateway
基于Pipeline实现的JT1078Gateway支持TCP/UDP,目前只支持http-flv、ws-flv、hls三种拉流方式
Stars: ✭ 50 (-95.3%)
Mutual labels:  hls, m3u8
hls-segment-reader
Node.js Readable for retrieving HLS segments.
Stars: ✭ 18 (-98.31%)
Mutual labels:  hls, m3u8
m3u8-downloader
Download the ts files according to the given m3u8 file.
Stars: ✭ 21 (-98.03%)
Mutual labels:  hls, m3u8
m3u8
Parse and generate m3u8 playlists for Apple HTTP Live Streaming (HLS) in Ruby.
Stars: ✭ 96 (-90.98%)
Mutual labels:  hls, m3u8
Android-hls
最近公司产品需要,调研hls(m3u8) aes-128 解密播放 . 分析 51Cto, 慕课
Stars: ✭ 73 (-93.14%)
Mutual labels:  hls, m3u8
Hlsdl
C program to download VoD HLS (.m3u8) files
Stars: ✭ 361 (-66.07%)
Mutual labels:  m3u8, hls
M3u8 Downloader
M3U8-Downloader 支持多线程、断点续传、加密视频下载缓存。
Stars: ✭ 369 (-65.32%)
Mutual labels:  m3u8, hls
Lal
🔥 Golang live stream lib/client/server. support RTMP/RTSP/HLS/HTTP[S]-FLV/HTTP-TS, H264/H265/AAC, relay, cluster, record, HTTP API/Notify, GOP cache. 官方文档见 https://pengrl.com/lal
Stars: ✭ 480 (-54.89%)
Mutual labels:  m3u8, hls
CBPlayer
一个内置P2P的神奇播放器
Stars: ✭ 60 (-94.36%)
Mutual labels:  hls, m3u8
hls-rip
Tool for ripping m3u8 playlists/segments.
Stars: ✭ 14 (-98.68%)
Mutual labels:  hls, m3u8
smart rtmpd
RTMP server, smart, compact, high performance(c, c++), high concurrency, easy to maintain, easy to deploy, (supports multiple operating systems Windows and Linux, ARM, FreeBSD)
Stars: ✭ 159 (-85.06%)
Mutual labels:  hls, m3u8
mock-hls-server
Fake a live/event HLS stream from a VOD one. Useful for testing. Supports looping.
Stars: ✭ 61 (-94.27%)
Mutual labels:  hls, m3u8
cordova-plugin-tencent-liteav
A cordova plugin for video playing with Tencent's LiteAV SDK. Support RTMP/HLS/FLV/MP4.
Stars: ✭ 24 (-97.74%)
Mutual labels:  hls, m3u8
Ios P2p Engine
Let your viewers become your unlimitedly scalable CDN.
Stars: ✭ 31 (-97.09%)
Mutual labels:  m3u8, hls
M3u8
A mini M3U8 downloader written in Golang for downloading and merging TS(Transport Stream) files. 一个迷你 M3U8 视频下载工具。
Stars: ✭ 215 (-79.79%)
Mutual labels:  m3u8, hls
hls-downloader
Download all video files from HLS (HTTP Live Streaming) VoD (Video on Demand) m3u8 playlist for local playback
Stars: ✭ 121 (-88.63%)
Mutual labels:  hls, m3u8
SharpGrabber
Download from YouTube, Vimeo, PornHub, HLS (M3U8 files) with .NET and JavaScript, Library and desktop app for downloading high quality media
Stars: ✭ 138 (-87.03%)
Mutual labels:  hls, m3u8

.. image:: https://travis-ci.org/globocom/m3u8.svg :target: https://travis-ci.org/globocom/m3u8

.. image:: https://coveralls.io/repos/globocom/m3u8/badge.png?branch=master :target: https://coveralls.io/r/globocom/m3u8?branch=master

.. image:: https://badge.fury.io/py/m3u8.svg :target: https://badge.fury.io/py/m3u8

m3u8

Python m3u8_ parser.

Documentation

Loading a playlist

To load a playlist into an object from uri, file path or directly from string, use the load/loads functions:

.. code-block:: python

import m3u8

playlist = m3u8.load('http://videoserver.com/playlist.m3u8')  # this could also be an absolute filename
print(playlist.segments)
print(playlist.target_duration)

# if you already have the content as string, use

playlist = m3u8.loads('#EXTM3U8 ... etc ... ')

Dumping a playlist

To dump a playlist from an object to the console or a file, use the dump/dumps functions:

.. code-block:: python

import m3u8

playlist = m3u8.load('http://videoserver.com/playlist.m3u8')
print(playlist.dumps())

# if you want to write a file from its content

playlist.dump('playlist.m3u8')

Supported tags

  • #EXT-X-TARGETDURATION_
  • #EXT-X-MEDIA-SEQUENCE_
  • #EXT-X-DISCONTINUITY-SEQUENCE_
  • #EXT-X-PROGRAM-DATE-TIME_
  • #EXT-X-MEDIA_
  • #EXT-X-PLAYLIST-TYPE_
  • #EXT-X-KEY_
  • #EXT-X-STREAM-INF_
  • #EXT-X-VERSION_
  • #EXT-X-ALLOW-CACHE
  • #EXT-X-ENDLIST_
  • #EXTINF_
  • #EXT-X-I-FRAMES-ONLY_
  • #EXT-X-BYTERANGE_
  • #EXT-X-I-FRAME-STREAM-INF_
  • #EXT-X-DISCONTINUITY_
  • #EXT-X-CUE-OUT
  • #EXT-X-CUE-OUT-CONT
  • #EXT-X-CUE-IN
  • #EXT-X-CUE-SPAN
  • #EXT-OATCLS-SCTE35
  • #EXT-X-INDEPENDENT-SEGMENTS_
  • #EXT-X-MAP_
  • #EXT-X-START_
  • #EXT-X-SERVER-CONTROL
  • #EXT-X-PART-INF
  • #EXT-X-PART
  • #EXT-X-RENDITION-REPORT
  • #EXT-X-SKIP
  • #EXT-X-SESSION-DATA_
  • #EXT-X-DATERANGE_
  • #EXT-X-GAP_

Encryption keys

The segments may be or not encrypted. The keys attribute list will be a list with all the different keys as described with #EXT-X-KEY_:

Each key has the next properties:

If no #EXT-X-KEY is found, the keys list will have a unique element None. Multiple keys are supported.

If unencrypted and encrypted segments are mixed in the M3U8 file, then the list will contain a None element, with one or more keys afterwards.

To traverse the list of keys available:

.. code-block:: python

import m3u8

m3u8_obj = m3u8.loads('#EXTM3U8 ... etc ...')
len(m3u8_obj.keys) => returns the number of keys available in the list (normally 1)
for key in m3u8_obj.keys:
   if key:  # First one could be None
      key.uri
      key.method
      key.iv

Getting segments encrypted with one key

There are cases where listing segments for a given key is important. It's possible to retrieve the list of segments encrypted with one key via by_key method in the segments list.

Example of getting the segments with no encryption:

.. code-block:: python

import m3u8

m3u8_obj = m3u8.loads('#EXTM3U8 ... etc ...')
segmk1 = m3u8_obj.segments.by_key(None)

# Get the list of segments encrypted using last key
segm = m3u8_obj.segments.by_key( m3u8_obj.keys[-1] )

With this method, is now possible also to change the key from some of the segments programmatically:

.. code-block:: python

import m3u8

m3u8_obj = m3u8.loads('#EXTM3U8 ... etc ...')

# Create a new Key and replace it
new_key = m3u8.Key("AES-128", "/encrypted/newkey.bin", None, iv="0xf123ad23f22e441098aa87ee")
for segment in m3u8_obj.segments.by_key( m3u8_obj.keys[-1] ):
    segment.key = new_key
# Remember to sync the key from the list as well
m3u8_obj.keys[-1] = new_key

Variant playlists (variable bitrates)

A playlist can have a list to other playlist files, this is used to represent multiple bitrates videos, and it's called variant streams. See an example here.

.. code-block:: python

variant_m3u8 = m3u8.loads('#EXTM3U8 ... contains a variant stream ...')
variant_m3u8.is_variant    # in this case will be True

for playlist in variant_m3u8.playlists:
    playlist.uri
    playlist.stream_info.bandwidth

the playlist object used in the for loop above has a few attributes:

  • uri: the url to the stream
  • stream_info: a StreamInfo object (actually a namedtuple) with all the attributes available to #EXT-X-STREAM-INF_
  • media: a list of related Media objects with all the attributes available to #EXT-X-MEDIA_
  • playlist_type: the type of the playlist, which can be one of VOD_ (video on demand) or EVENT_

NOTE: the following attributes are not implemented yet, follow issue 4_ for updates

  • alternative_audios: its an empty list, unless it's a playlist with Alternative audio, in this case it's a list with Media objects with all the attributes available to #EXT-X-MEDIA
  • alternative_videos: same as alternative_audios

A variant playlist can also have links to I-frame playlists, which are used to specify where the I-frames are in a video. See Apple's documentation on this for more information. These I-frame playlists can be accessed in a similar way to regular playlists.

.. code-block:: python

variant_m3u8 = m3u8.loads('#EXTM3U ... contains a variant stream ...')

for iframe_playlist in variant_m3u8.iframe_playlists:
    iframe_playlist.uri
    iframe_playlist.iframe_stream_info.bandwidth

The iframe_playlist object used in the for loop above has a few attributes:

  • uri: the url to the I-frame playlist
  • base_uri: the base uri of the variant playlist (if given)
  • iframe_stream_info: a StreamInfo object (same as a regular playlist)

Custom tags

Quoting the documentation::

Lines that start with the character '#' are either comments or tags.
Tags begin with #EXT.  They are case-sensitive.  All other lines that
begin with '#' are comments and SHOULD be ignored.

This library ignores all the non standard tags by default. If you want them to be collected while loading the file content, you need to pass a function to the load/loads functions, following the example below:

.. code-block:: python

import m3u8

def get_movie(line, data, lineno):
    if line.startswith('#MOVIE-NAME:'):
        custom_tag = line.split(':')
        data['movie'] = custom_tag[1].strip()

m3u8_obj = m3u8.load('http://videoserver.com/playlist.m3u8', custom_tags_parser=get_movie)
print(m3u8_obj.data['movie'])  #  million dollar baby

Using different HTTP clients

If you don't want to use urllib to download playlists, having more control on how objects are fetched over the internet, you can use your own client. requests is a well known Python HTTP library and it can be used with m3u8:

.. code-block:: python

import m3u8
import requests

class RequestsClient():
    def download(self, uri, timeout=None, headers={}, verify_ssl=True):
        o = requests.get(uri, timeout=timeout, headers=headers)
        return o.text, o.url

playlist = m3u8.load('http://videoserver.com/playlist.m3u8', http_client=RequestsClient())
print(playlist.dumps())

The advantage of using a custom HTTP client is to refine SSL verification, proxies, performance, flexibility, etc.

Playlists behind proxies

In case you need to use a proxy but can't use a system wide proxy (HTTP/HTTPS proxy environment variables), you can pass your HTTP/HTTPS proxies as a dict to the load function.

.. code-block:: python

import m3u8

proxies = {
    'http': 'http://10.10.1.10:3128',
    'https': 'http://10.10.1.10:1080',
}

http_client = m3u8.httpclient.DefaultHTTPClient(proxies)
playlist = m3u8.load('http://videoserver.com/playlist.m3u8', http_client=http_client)  # this could also be an absolute filename
print(playlist.dumps())

It works with the default client only. Custom HTTP clients must implement this feature.

Running Tests

.. code-block:: bash

$ ./runtests

Contributing

All contribution is welcome, but we will merge a pull request if, and only if, it

  • has tests
  • follows the code conventions

If you plan to implement a new feature or something that will take more than a few minutes, please open an issue to make sure we don't work on the same thing.

.. _m3u8: https://tools.ietf.org/html/rfc8216 .. _#EXT-X-VERSION: https://tools.ietf.org/html/rfc8216#section-4.3.1.2 .. _#EXTINF: https://tools.ietf.org/html/rfc8216#section-4.3.2.1 .. _#EXT-X-BYTERANGE: https://tools.ietf.org/html/rfc8216#section-4.3.2.2 .. _#EXT-X-DISCONTINUITY: https://tools.ietf.org/html/rfc8216#section-4.3.2.3 .. _#EXT-X-KEY: https://tools.ietf.org/html/rfc8216#section-4.3.2.4 .. _#EXT-X-MAP: https://tools.ietf.org/html/rfc8216#section-4.3.2.5 .. _#EXT-X-PROGRAM-DATE-TIME: https://tools.ietf.org/html/rfc8216#section-4.3.2.6 .. _#EXT-X-DATERANGE: https://tools.ietf.org/html/rfc8216#section-4.3.2.7 .. _#EXT-X-TARGETDURATION: https://tools.ietf.org/html/rfc8216#section-4.3.3.1 .. _#EXT-X-MEDIA-SEQUENCE: https://tools.ietf.org/html/rfc8216#section-4.3.3.2 .. _#EXT-X-DISCONTINUITY-SEQUENCE: https://tools.ietf.org/html/rfc8216#section-4.3.3.3 .. _#EXT-X-ENDLIST: https://tools.ietf.org/html/rfc8216#section-4.3.3.4 .. _#EXT-X-PLAYLIST-TYPE: https://tools.ietf.org/html/rfc8216#section-4.3.3.5 .. _#EXT-X-I-FRAMES-ONLY: https://tools.ietf.org/html/rfc8216#section-4.3.3.6 .. _#EXT-X-MEDIA: https://tools.ietf.org/html/rfc8216#section-4.3.4.1 .. _#EXT-X-STREAM-INF: https://tools.ietf.org/html/rfc8216#section-4.3.4.2 .. _#EXT-X-I-FRAME-STREAM-INF: https://tools.ietf.org/html/rfc8216#section-4.3.4.3 .. _#EXT-X-SESSION-DATA: https://tools.ietf.org/html/rfc8216#section-4.3.4.4 .. _#EXT-X-INDEPENDENT-SEGMENTS: https://tools.ietf.org/html/rfc8216#section-4.3.5.1 .. _#EXT-X-START: https://tools.ietf.org/html/rfc8216#section-4.3.5.2 .. _#EXT-X-DATERANGE: https://tools.ietf.org/html/rfc8216#section-4.3.2.7 .. _#EXT-X-GAP: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-05#section-4.4.2.7 .. _issue 1: https://github.com/globocom/m3u8/issues/1 .. _variant streams: https://tools.ietf.org/html/rfc8216#section-6.2.4 .. _example here: http://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-8.5 .. _issue 4: https://github.com/globocom/m3u8/issues/4 .. _I-frame playlists: https://tools.ietf.org/html/rfc8216#section-4.3.4.3 .. _Apple's documentation: https://developer.apple.com/library/ios/technotes/tn2288/_index.html#//apple_ref/doc/uid/DTS40012238-CH1-I_FRAME_PLAYLIST .. _Alternative audio: http://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-8.7 .. _VOD: https://developer.apple.com/library/mac/technotes/tn2288/_index.html#//apple_ref/doc/uid/DTS40012238-CH1-TNTAG2 .. _EVENT: https://developer.apple.com/library/mac/technotes/tn2288/_index.html#//apple_ref/doc/uid/DTS40012238-CH1-EVENT_PLAYLIST

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].