Part.1 《Ts和Mp4》
参考:https://stackoverflow.com/questions/11762464/what-is-difference-between-mp4-and-mpegts
以下内容为原文和本人重点翻译
- 如下回答
MPEG-TS is designed for live streaming of events over DVB, UDP multicast, but also over HTTP. It divides the stream in elementary streams, which are segmented in small chunks. System information is sent at regular intervals, so the receiver can start playing the stream any time.
MPEG-TS isn't good for streaming files,
because it doesn't provide info about the duration of the movie or song
, as well as the points you canseek
to.There are some new protocols that can use MPEG-TS for streaming over HTTP,
that put additional metadata in files and fix the disadvantage I talked before.
These areHTTP Live Streaming
and DASH (Dynamic adaptive streaming over HTTP).On the other hand MP4 has that info in part of the stream, called moov atom. The point is that the moov must be placed before the media content and downloaded from the server first.
This way the video player knows the duration and can seek to any point without downloading the whole file
(this is called HTTP pseudostreaming).Sadly ffmpeg places the moov at the end of the file. You can fix that with software like Xmoov-PHP.
Here you can find more info about pseudostreaming.
如上 ^^^ ,翻译一下 划了一些重点
主要说了以下几点:
- .ts文件不提供关于时长等信息,你无法在ts文件里去实现音视频的seek操作
- .mp4不同于ts,是提供了时长等信息,可以执行seek到指定位置
- .ts文件一般用于m3u8中, 或者提供了流媒体基础信息的前提下使用
- .mp4文件可以在不下载完全媒体文件的前提下进行seek操作;因为其头部记录moov信息(
moov box 中包含编码、分辨率、码率、帧率、时长、音频采样率等等媒体信息
)
在无特殊情况下很多回答都推荐mp4, https://forums.tomshardware.com/threads/ts-vs-mp4-format-which-is-better.1765493/
Part.2 《关于MP4》
1. 传统的 MP4 文件格式
MP4 容器是由很多个 box 组成的,传统的 MP4 文件由 ftyp box、moov box、mdat box 组成。
moov box 中包含编码、分辨率、码率、帧率、时长、音频采样率等等媒体信息;mdat box 中包含音视频的媒体数据。
一般来讲 moov box 在文件的开头,也有在文件尾的情况,这样播放器需要扫描到文件结尾,才能读取媒体信息,导致起拨时间太长;mdat box 一个文件中一般只有一个。
2. Fragmented MP4 文件格式
Fragmented MP4 文件结构如图所示:
Fragmented MP4 以 Fragment 的方式存储视频信息。每个 Fragment 由一个 moof box 和一个 mdat box 组成。
moof box 中存放的是该 Fragment 中 mdat 的视频分片的描述信息,读取 moof box 即可对该 Fragment 进行解码播放。
Fragmented MP4 中的 moov box 只存储文件级别的媒体信息,因此 moov box 的体积比传统的 MP4 中的 moov box 体积要小很多。
3. MPEG-DASH 协议
MPEG-DASH (Dynamic Adaptive Streaming over HTTP)协议是一种类似于 HLS 协议的码率自适应方案。
MPEG-DASH 使用 XML格式的 MPD(Media Presentation Description)文件来描述码流的详细信息,类似于 HLS 的 m3u8 文件。
MPD 文件结构:https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html
下面是两个 MPD 文件的例子:
<?xml version="1.0" ?>
<MPD mediaPresentationDuration="PT10M34.533S" minBufferTime="PT4.58S" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
<!-- Created with Bento4 mp4-dash.py, VERSION=1.7.0-610 -->
<Period>
<!-- Audio -->
<AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1">
<SegmentTemplate duration="4583" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1" timescale="1000"/>
<Representation audioSamplingRate="48000" bandwidth="162758" codecs="mp4a" id="audio/und">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
</AdaptationSet>
<!-- Video -->
<AdaptationSet maxHeight="1080" maxWidth="1920" mimeType="video/mp4" minHeight="1080" minWidth="1920" segmentAlignment="true" startWithSAP="1">
<SegmentTemplate duration="4583" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/seg-$Number$.m4s" startNumber="1" timescale="1000"/>
<Representation bandwidth="5908997" codecs="avc1.640029" frameRate="30" height="1080" id="video/1" scanType="progressive" width="1920"/>
</AdaptationSet>
</Period>
</MPD>
<?xml version="1.0"?>
<!-- MPD file Generated with GPAC version 0.5.1-DEV-rev4984 on 2014-01-27T22:05:18Z-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500000S" type="static" mediaPresentationDuration="PT0H2M56.37S" profiles="urn:mpeg:dash:profile:full:2011">
<ProgramInformation moreInformationURL="http://gpac.sourceforge.net">
<Title>sample_dash.mpd generated by GPAC</Title>
</ProgramInformation>
<Period id="" duration="PT0H2M56.37S">
<AdaptationSet segmentAlignment="true" maxWidth="1280" maxHeight="720" maxFrameRate="30" par="16:9">
<ContentComponent id="1" contentType="video" lang="eng"/>
<ContentComponent id="2" contentType="audio" lang="eng"/>
<Representation id="1" mimeType="video/mp4" codecs="avc1.4d0020,mp4a.40.2" width="1280" height="720" frameRate="30" sar="1:1" audioSamplingRate="48000" startWithSAP="1" bandwidth="917965">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>sample_dashinit.mp4</BaseURL>
<SegmentList timescale="1000" duration="9335">
<Initialization range="0-94558"/>
<SegmentURL mediaRange="94559-1126981" indexRange="94559-94699"/>
<SegmentURL mediaRange="1126982-2128137" indexRange="1126982-1127122"/>
<SegmentURL mediaRange="2128138-3217574" indexRange="2128138-2128278"/>
...
<SegmentURL mediaRange="19425183-20239268" indexRange="19425183-19425323"/>
</SegmentList>
</Representation>
</AdaptationSet>
</Period>
</MPD>
4. 生成 Fragmented MP4 以及 MPD 文件
使用 Bento4 的 mp4fragment 命令来生成 fragmented mp4,使用 mp4dash 命令来生成 MPD 文件。
mp4fragment input.mp4 fragmented.mp4
mp4dash -o output fragmented.mp4
对应的 MPD 文件就是上面第一个例子。