Earthling
Earthling

Reputation: 457

MPEG-DASH(.mpd) implementation similar to my existing methods written currently for .m3u8

I have the following 2 methods written in python which have been implemented for .m3u8 playlist files

My purpose is to do the same for .mpd manifest files as well. Eventual outcome desired is to have 4 methods : 2 listed above for .m3u8 and 2 for .mpd manifest file.

I'm currently using the following package for working with .m3u8 (HLS) playlist files

https://github.com/globocom/m3u8

I'm searched to find a similar implementation for .mpd(MPEG-DASH) manifest files but all I found were parsers like the following:

https://github.com/sangwonl/python-mpegdash

https://github.com/avishaycohen/mpd-parser

Any help on implementing similar to the 2 methods to allow for .mpd files and doing the exact same things which the 2 methods do.


import logging
from datetime import timedelta
from os.path import basename

from furl import furl
from m3u8 import M3U8, Media, Playlist, Segment
from m3u8 import load as load_m3u8

def make_master_manifest(request, stream):
    if stream.info:
        bandwidth = int(stream.info["bw_out"])
        width = stream.info["meta"]["video"]["width"]
        height = stream.info["meta"]["video"]["height"]
        stream_info = {
            "bandwidth": bandwidth,
            "resolution": f"{width}x{height}",
            "codecs": "avc1.640028,mp4a.40.2",
        }
    else:
        stream_info = {"bandwidth": 1000}

    p = Playlist(basename(stream.index_manifest_url), stream_info, None, None)
    m = M3U8()
    m.add_playlist(p)

    for feed in stream.feeds.all():
        media = Media(
            type="SUBTITLES",
            group_id="feeds",
            name=f"feed-{feed.uuid}",
            language="en",
            default="YES",
            autoselect="YES",
            uri=furl(feed.manifest_url).set({"stream": stream.uuid}).url,
        )
        p.media.append(media)
        m.add_media(media)

    return m.dumps()


def make_feed_manifest(request, stream, feed):
    url = request.build_absolute_uri(stream.index_manifest_url)
    p = load_m3u8(url)
    m = M3U8()
    m.version = p.version
    m.target_duration = p.target_duration
    m.media_sequence = p.media_sequence
    for s in p.segments:
        if not m.program_date_time:
            m.program_date_time = s.current_program_date_time

        vtt_url = furl(basename(feed.webvtt_url)).set({"stream": stream.uuid})
        if s.current_program_date_time:
            vtt_url.args.update(
                {
                    "start": s.current_program_date_time.isoformat(),
                    "end": (
                        s.current_program_date_time + timedelta(seconds=s.duration)
                    ).isoformat(),
                    "epoch": stream.started_at.isoformat(),
                }
            )
        v = Segment(
            base_uri=vtt_url.url,
            uri=vtt_url.url,
            duration=s.duration,
            discontinuity=s.discontinuity,
            program_date_time=s.current_program_date_time,
        )
        m.add_segment(v)

    return m.dumps()

Help appreciated.

Note. The above methods are created for .m3u8 playlist files. I attempted to implement on using similar logic for an taking an .mpd file but failed to do so using existing package parsers. The packages have parsers only but no methods like the one in the m3u8 package listed above. I'm hopeful stack users could help me implement similar to the 2 methods for an .mpd manifest file as input.

Upvotes: 0

Views: 77

Answers (0)

Related Questions