Giter VIP home page Giter VIP logo

hls-to-dash's Introduction

Build status

Description

This is an open source video streaming packager and toolkit to rewrap live HLS streams to live MPEG DASH streams.

Features

  • Generate single period MPEG DASH for live based on an HLS live stream
  • Generate multi period MPEG DASH for live based on an HLS live stream with SCTE35 splicing
  • Rewrap MPEG2 TS segment to fragmented MP4

Usage

Install

Installation from Python package index:

 pip install hls2dash

Installation from source:

 python setup.py install

Running

Generate Single period MPEG DASH:

 hls-to-dash http://example.com/master.m3u8 > stream.mpd

Generate Multi period MPEG DASH:

 hls-to-dash http://example.com/master.m3u8 --multi > stream.mpd

Rewrap MPEG2 TS segment to fragmented MP4

 ts-to-fmp4 master2500_19274.ts 2500_19274.dash

or when TS segment is on a remote server

 ts-to-fmp4 http://example.com/master2500_19274.ts 2500_19274.dash

Help

hls-to-dash

usage: hls-to-dash [-h] [--multi] [--ctx CTX] [--ctxdir CTXDIR] [--debug]
                   PLAYLIST

Generate single and multi period MPEG DASH manifest from a live HLS source.
Writes MPEG DASH manifest to stdout.

Currently assumes that HLS variant is named as 'master[PROFILE].m3u8'
  master2500.m3u8, master1500.m3u8
and that the segments are named as 'master[PROFILE]_[SEGNO].ts'
  master2500_34202.ts, master1500_34202.ts

positional arguments:
  PLAYLIST         Path to HLS playlist file. Can be a URI or local file.

optional arguments:
  -h, --help       show this help message and exit
  --multi          Generate multi period MPEG DASH on EXT-X-CUE markers in HLS
  --ctx CTX        Name of DASH session file
  --ctxdir CTXDIR  Where to store DASH session file. Defaults to /tmp/
  --debug          Write debug info to stderr

ts-to-fmp4

usage: ts-to-fmp4 [-h] [--outdir OUTDIR] [--debug] TSFILE OUTPUT

Rewrap a MPEG2 TS segment to a fragmented MP4

positional arguments:
  TSFILE           Path to TS file. Can be a URI or local file.
  OUTPUT           Output file name

optional arguments:
  -h, --help       show this help message and exit
  --outdir OUTDIR  Directory where the fragmented MP4 will be stored. Default is current directory
  --debug          Write debug info to stderr

hls-to-dash's People

Contributors

birme avatar kjellc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hls-to-dash's Issues

Issues with gaps between periods

This issue was reported by Vincent Tomasi [email protected] identifying problems with gaps between periods:

There are several issues reported on Shaka Player (shaka-project/shaka-player#381, shaka-project/shaka-player#384) stating it is not able to manage Period gaps.
If you look at the attached manifest [1], when it occured, there actually is a gap between the two audio Periods (video is fine):

  • video: 2319715431 + 5x900000 + 417600 = 2324633031
  • audio: 1237181563 + 5x480000 + 222719 = 1239804282 (but 1239804283 in the manifest)

When there is no gap, the player plays the stream fine, but even the slightest gap seems to disrupt the player.

[1] period-gap.mpd.txt

hls-to-dash generates invalid mpd files

Hello there,

I am using hls-to-dash to generate a Multi period MPEG DASH from a master HLS playlist, as shown below:

  1. FFmpeg snippet used to encode:
/home/lin/bin/ffmpeg -loglevel debug -threads 4 -filter_complex_threads 4 -vsync 1 -i '/home/lin/Desktop/src/sowdtow.webm' -filter_complex \
"['v:0']split=2[s0][s1]; \
 [s0]scale=w=1920:h=1080:force_original_aspect_ratio=decrease:flags=lanczos,yadif[v0]; \
 [s1]scale=w=1280:h=720:force_original_aspect_ratio=decrease:flags=lanczos,yadif[v1]" \
-bsf:a aac_adtstoasc \
-b:v:0 6750k -c:v h264_nvenc -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 \
-b:v:1 5250k -c:v h264_nvenc -preset llhq -rc:v vbr_hq -pix_fmt yuv420p -profile:v main -level 4.1 \
-b:a:0 256k -b:a:1 192k -c:a aac -ar 48000 \
-map "[v0]" -map "[v1]" -map 0:a:0 -map 0:a:0 \
-f hls -hls_flags discont_start+split_by_time -hls_time 10 -hls_init_time 4 -hls_list_size 10 -hls_wrap 24 \
-var_stream_map "v:0,a:0 v:1,a:1" -master_pl_publish_rate 10 -master_pl_name master.m3u8 \
"/home/lin/Desktop/dest/vs%v/master.m3u8"
  1. Snippet used to create the multi-period DASH:

hls-to-dash /home/lin/Desktop/dest/master.m3u8 --multi > /home/lin/Desktop/dest/mpd/test.mpd

  1. Output from hls-to-dash:
<?xml version="1.0"?>
<!-- Created with hls2dash (version=0.2.2) -->
<!-- https://pypi.python.org/pypi/hls2dash -->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:scte35="urn:scte:scte35:2014:xml+bin" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="dynamic" minimumUpdatePeriod="PT10S" minBufferTime="PT1.500S" maxSegmentDuration="PT10.000000S" availabilityStartTime="2018-03-28T23:18:49.8
39191Z" publishTime="2018-03-28T20:20:21.250450Z">
  <Period id="8227010" start="PT91.411222S">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d4029" minWidth="1280" maxWidth="1920" minHeight="720" maxHeight="1080" startWithSAP="1" segmentAlignment="true" minBandwidth="5986200" maxBandwidth="7706600">
      <SegmentTemplate timescale="90000" media="$RepresentationID$_$Number$.dash" presentationTimeOffset="8227010" startNumber="16">
        <SegmentTimeline>
          <S t="8227010" d="900900" />
          <S d="900900" />
          <S d="897897" />
          <S d="900900" />
          <S d="900900" />
          <S d="897897" />
          <S d="900900" />
          <S d="900900" />
          <S d="897897" />
          <S d="192192" />
        </SegmentTimeline>
      </SegmentTemplate>
      <Representation id="video-0/master" width="1920" height="1080" bandwidth="7706600" scanType="progressive" />
      <Representation id="video-1/master" width="1280" height="720" bandwidth="5986200" scanType="progressive" />
    </AdaptationSet>
    <AdaptationSet mimeType="audio/mp4" codecs="mp4a.40.2">
      <SegmentTemplate timescale="48000" media="$RepresentationID$_$Number$.dash" presentationTimeOffset="4387738" startNumber="16">
        <SegmentTimeline>
          <S t="4387739" d="480480" />
          <S d="480480" />
          <S d="478878" />
          <S d="480480" />
          <S d="480480" />
          <S d="478878" />
          <S d="480480" />
          <S d="480480" />
          <S d="478878" />
          <S d="102502" />
        </SegmentTimeline>
      </SegmentTemplate>
      <Representation id="audio-0/master" bandwidth="96000" />
    </AdaptationSet>
  </Period>
</MPD>
  1. Stream generated with MP4Box from the same master playlist:

MP4Box -mpd /home/lin/Desktop/dest/master.m3u8 -out /home/lin/Desktop/dest/mpd/stream.mpd

Content:

<MPD type="static" xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:hls="urn:gpac:hls:aes:mpd:2015" profiles="urn:mpeg:dash:profile:full:2011" id="master.m3u8" mediaPresentationDuration="PT92S" minBufferTime="PT1.5S">
 <ProgramInformation moreInformationURL="http://gpac.sourceforge.net">
  <Title>/home/lin/Desktop/dest/vs1/master.m3u8</Title>
  <Source>Generated from URL /home/lin/Desktop/dest/master.m3u8</Source>
  <Copyright>Generated by GPAC 0.5.2-DEV-revVersion: 0.5.2-426-gc5ad4e4+dfsg5-1build1 from /home/lin/Desktop/dest/master.m3u8</Copyright>
 </ProgramInformation>
 <Period start="PT0S" duration="PT92S" >
  <AdaptationSet segmentAlignment="true">
   <Representation id="master.m3u8" bandwidth="7706600" mimeType="video/mp2t" codecs="avc1.4d4029,mp4a.40.2" width="1920" height="1080">
    <BaseURL>/home/lin/Desktop/dest/vs0/</BaseURL>
    <SegmentList duration="10.000000">
     <SegmentURL media="master16.ts"/>
     <SegmentURL media="master17.ts"/>
     <SegmentURL media="master18.ts"/>
     <SegmentURL media="master19.ts"/>
     <SegmentURL media="master20.ts"/>
     <SegmentURL media="master21.ts"/>
     <SegmentURL media="master22.ts"/>
     <SegmentURL media="master23.ts"/>
     <SegmentURL media="master0.ts"/>
     <SegmentURL media="master1.ts"/>
    </SegmentList>
   </Representation>
   <Representation id="master.m3u8" bandwidth="5986200" mimeType="video/mp2t" codecs="avc1.4d4029,mp4a.40.2" width="1280" height="720">
    <BaseURL>/home/lin/Desktop/dest/vs1/</BaseURL>
    <SegmentList duration="10.000000">
     <SegmentURL media="master16.ts"/>
     <SegmentURL media="master17.ts"/>
     <SegmentURL media="master18.ts"/>
     <SegmentURL media="master19.ts"/>
     <SegmentURL media="master20.ts"/>
     <SegmentURL media="master21.ts"/>
     <SegmentURL media="master22.ts"/>
     <SegmentURL media="master23.ts"/>
     <SegmentURL media="master0.ts"/>
     <SegmentURL media="master1.ts"/>
    </SegmentList>
   </Representation>
  </AdaptationSet>
 </Period>
</MPD>

You'll notice that the DASH manifest generated by hls-to-dash lacks the <SegmentURL> sections, and the output is unusable:

cd ~/Desktop/dest/mpd
MP4Client test.mpd 
Using config file in /home/lin/.gpac directory
System info: 64310 MB RAM - 8 cores
Modules Found : 35 
Loading GPAC Terminal
[Thread MediaManager] Couldn't set priority(2) for thread ID 0x86a96700
[Thread MediaManager] Couldn't set priority(2) for thread ID 0x86a96700
Terminal Loaded in 47 ms
Opening URL test.mpd
[DASH] Slight drift in UTC clock at time 2018-03-28T23:18:49Z: diff AST - now 9998969 ms
[DASH] current time 0 is before start time 8227010 of first segment in timeline (timescale 90000) by 91.4112 sec - using first segment as starting point
[DASH] Slight drift in UTC clock at time 2018-03-28T23:18:49Z: diff AST - now 9998969 ms
[DASH] current time 0 is before start time 4387739 of first segment in timeline (timescale 48000) by 91.4112 sec - using first segment as starting point
[IsoMedia] : error while opening video-1/master_16.dash, error=Requested URL is not valid or cannot be found
[IsoMedia] : error while opening audio-0/master_16.dash, error=Requested URL is not valid or cannot be found
Service Connected

Whereas the stream generated by MP4Box are indeed usable:

MP4Client stream.mpd 
Using config file in /home/lin/.gpac directory
System info: 64310 MB RAM - 8 cores
Modules Found : 35 
Loading GPAC Terminal
[Thread MediaManager] Couldn't set priority(2) for thread ID 0x43ffe700
[Thread MediaManager] Couldn't set priority(2) for thread ID 0x43ffe700
Terminal Loaded in 82 ms
Opening URL stream.mpd
Service Connected

And playable.

Filing this issue as a bug.

AttributeError: HLS instance has no attribute 'representations'

In my practice, when using such command,it throws following error:
hls-to-dash "http://10.47.235.113:8001/local/hls/content/00000000020000000022_,1,2,.mp4.urlset/index.m3u8" > stream.mpd

AttributeError: HLS instance has no attribute 'representations'

index.m3u8 list:
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1263919,RESOLUTION=1280x720,FRAME-RATE=25.000,CODECS="avc1.640029,mp4a.40.2"
1-f1-v1-a1.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1195925,RESOLUTION=1104x622,FRAME-RATE=50.000,CODECS="avc1.64001f,mp4a.40.2"
1-f2-v1-a1.m3u8

AttributeError: 'NoneType' object has no attribute 'split'

Hello there,

Using this tool to generate Multi period MPEG DASH fails with the error above:

hls-to-dash /path-to-master-playlist/master.m3u8 --multi > /outdir/mpd/stream.mpd

Output:

Traceback (most recent call last):
  File "/usr/local/bin/hls-to-dash", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/hls2dash/__init__.py", line 36, in main
    mpd.load()
  File "/usr/local/lib/python2.7/dist-packages/hls2dash/lib/MPD.py", line 231, in load
    self._parseMaster(m3u8_obj)
  File "/usr/local/lib/python2.7/dist-packages/hls2dash/lib/MPD.py", line 412, in _parseMaster
    (video_codec, audio_codec) = stream.codecs.split(',')
AttributeError: 'NoneType' object has no attribute 'split'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.