基于现有HLS(.m3u8) Python实现,构建MPEG-DASH(.mpd)的主清单与Feed清单生成方法
基于现有HLS(.m3u8) Python实现,构建MPEG-DASH(.mpd)的主清单与Feed清单生成方法
我已经用Python完成了针对.m3u8(HLS)播放列表的两个核心方法:
- 生成主清单(Master Manifest)
- 生成Feed清单(Feed Manifest)
现在我想把同样的逻辑复用到.mpd(MPEG-DASH)清单文件上,最终目标是拥有4个方法:2个处理HLS格式,2个处理DASH格式,且DASH的两个方法要和HLS版本完成完全相同的业务逻辑。
现有HLS实现的依赖
目前我处理HLS用的是m3u8库,它非常实用——不仅能解析.m3u8文件,还提供了一套完整的构建API(比如M3U8、Playlist、Media、Segment这些类),让我可以轻松组装出符合要求的清单文件。
遇到的问题:DASH工具的局限性
我搜索了一圈处理MPEG-DASH的Python库,但找到的都是解析器,比如python-mpegdash和mpd-parser。它们只能读取、解析.mpd文件的内容,却没有像m3u8那样的构建/生成能力——我没法用它们来创建新的.mpd清单,或者修改现有清单并输出。
现有HLS方法代码(供参考)
下面是我现有的HLS实现,DASH的方法需要和这些逻辑一一对应:
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()
具体需求
我需要实现两个对应DASH格式的方法:
make_master_manifest_mpd(request, stream):和HLS版本逻辑一致,生成包含对应码率、分辨率信息,以及关联字幕Feed引用的DASH主清单make_feed_manifest_mpd(request, stream, feed):基于原DASH索引清单,生成包含对应WebVTT片段的Feed清单
不管是基于现有解析器扩展,还是直接手动拼接XML(毕竟.mpd本质是XML文档),只要能实现和现有HLS方法完全相同的功能就行,求各位大佬给点思路或者实现方案!
备注:内容来源于stack exchange,提问作者Ananth




