如何在Android本地创建MPD文件并直接传入ExoPlayer?
本地构建MPD并传入ExoPlayer 2.6.0的实现思路
嘿,我来给你梳理下在Android本地构建MPD并直接传给ExoPlayer 2.6.0的可行思路,不用依赖远程服务器,分几种方案供你参考:
方案1:直接构建DashManifest对象(推荐,无需XML解析)
其实你完全不用先生成MPD XML文件,ExoPlayer允许直接通过代码实例化DashManifest及其内部组件,跳过XML解析步骤,效率更高:
- 核心思路:逐个创建DASH规范中的核心对象,从最底层的
Representation(代表不同码率/分辨率的媒体流),到AdaptationSet(同类型媒体流的集合,比如所有视频流、所有音频流),再到Period(媒体的一个时间段,单Period足够大部分场景),最后组合成DashManifest。 - 代码示例(适配ExoPlayer 2.6.0):
// 1. 创建视频Representation(以1080P、5Mbps码率为例) Representation videoRep = new Representation( 0, // 唯一ID 0, // 版本ID Format.createVideoSampleFormat( null, MimeTypes.VIDEO_H264, // 视频编码格式 null, Format.NO_VALUE, Format.NO_VALUE, 1920, // 宽度 1080, // 高度 Format.NO_VALUE, 5000000, // 码率(bps) null, null, 0 // 帧率 ), Uri.fromFile(new File(getFilesDir(), "video_1080p.mp4")), // 本地视频文件Uri null, // 初始化段Uri(单文件可设为null) 0, // 初始化段起始偏移 -1 // 初始化段长度(-1表示到文件末尾) ); // 2. 构建视频AdaptationSet AdaptationSet videoAdaptationSet = new AdaptationSet( 0, // 唯一ID AdaptationSet.TYPE_VIDEO, // 类型:视频 Collections.singletonList(videoRep), null, null, null, null // 其他属性可根据需求设置 ); // 3. 构建Period Period period = new Period( 0, // 唯一ID 0, // 起始时间 Collections.singletonList(videoAdaptationSet), null, null, null // 可添加音频、字幕等AdaptationSet ); // 4. 最终构建DashManifest DashManifest manifest = new DashManifest( DashManifest.TYPE_STATIC, // 静态MPD 3600000, // 总时长(毫秒,这里是1小时) Collections.singletonList(period), null, null, null // 其他属性可设为null ); // 5. 创建媒体源并传入ExoPlayer DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "YourAppName")); DashMediaSource mediaSource = new DashMediaSource.Factory(dataSourceFactory) .createMediaSource(manifest); // 最后将mediaSource设置给ExoPlayer即可播放 player.prepare(mediaSource);
- 注意:ExoPlayer 2.6.0的API和新版本有差异,比如
Representation的构造参数,一定要对照该版本的官方文档调整参数。
方案2:本地生成MPD XML文件,通过本地Uri加载
如果你更习惯使用MPD XML格式,可以在本地生成XML文件后,用本地Uri传给ExoPlayer:
- 核心步骤:
- 手动拼接或用XML工具生成符合DASH规范的MPD XML字符串,注意所有媒体文件的
BaseURL要指向本地路径(比如file:///storage/emulated/0/your_video.mp4) - 将XML字符串写入App缓存目录或内部存储的文件中
- 用本地文件Uri创建
DashMediaSource,ExoPlayer会自动调用DashManifestParser解析本地MPD
- 手动拼接或用XML工具生成符合DASH规范的MPD XML字符串,注意所有媒体文件的
- 代码示例:
// 1. 拼接简化版MPD XML内容 String mpdContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\" type=\"static\" mediaPresentationDuration=\"PT1H0M0S\" minBufferTime=\"PT10S\">\n" + " <Period id=\"0\" start=\"PT0S\">\n" + " <AdaptationSet mimeType=\"video/mp4\" codecs=\"avc1.4D401E\">\n" + " <Representation id=\"0\" bandwidth=\"5000000\" width=\"1920\" height=\"1080\">\n" + " <BaseURL>file://" + new File(getFilesDir(), "video_1080p.mp4").getAbsolutePath() + "</BaseURL>\n" + " </Representation>\n" + " </AdaptationSet>\n" + " </Period>\n" + "</MPD>"; // 2. 将XML写入本地缓存文件 File mpdFile = new File(getCacheDir(), "local_dash.mpd"); try (FileWriter writer = new FileWriter(mpdFile)) { writer.write(mpdContent); } catch (IOException e) { e.printStackTrace(); } // 3. 通过本地Uri加载MPD Uri mpdUri = Uri.fromFile(mpdFile); DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "YourAppName")); DashMediaSource mediaSource = new DashMediaSource.Factory(dataSourceFactory) .createMediaSource(mpdUri); player.prepare(mediaSource);
- 注意:如果媒体文件在外部存储,需要申请
READ_EXTERNAL_STORAGE权限;内部存储的App私有目录无需额外权限。
方案3:解析内存中的MPD XML字符串(无需写入文件)
如果你不想生成本地文件,可以直接在内存中解析MPD XML字符串:
- 核心步骤:
- 生成MPD XML字符串
- 将字符串转为
ByteArrayInputStream - 用
DashManifestParser解析输入流得到DashManifest对象 - 用该对象创建媒体源
- 代码示例:
String mpdContent = "..."; // 同方案2的MPD XML内容 InputStream inputStream = new ByteArrayInputStream(mpdContent.getBytes(StandardCharsets.UTF_8)); // 解析内存中的XML流 DashManifestParser parser = new DashManifestParser(); DashManifest manifest = parser.parse(null, inputStream); // 第一个参数为解析上下文Uri,可传null // 创建媒体源 DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "YourAppName")); DashMediaSource mediaSource = new DashMediaSource.Factory(dataSourceFactory) .createMediaSource(manifest); player.prepare(mediaSource);
额外注意事项
- 版本适配:ExoPlayer 2.6.0是比较老的版本,部分API在后续版本中已被重构,务必参考该版本的官方文档编写代码。
- 媒体格式:确保本地媒体文件是MP4格式(带moov原子),ExoPlayer支持单文件DASH播放,无需预先分段。
- 权限:涉及外部存储时,要处理好运行时权限申请。
内容的提问来源于stack exchange,提问作者Adrián García Campos
相关产品推荐
相关产品推荐

