问题标签 [fmp4]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
ffmpeg - 如何使用 MSE SourceBuffer 播放和寻找碎片化的 MP4 音频?
笔记:
如果您最终来到这里,您可能想看看shaka-player和随附的shaka-streamer。用它。除非你真的必须这样做,否则不要自己实现。
我现在尝试了很长一段时间,以便能够在 Chrome、Firefox、Safari 等上播放音轨,但我一直在碰壁。我目前的问题是我无法在碎片化的 MP4(或 MP3)中寻找。
目前,我正在将 MP3 等音频文件转换为分段 MP4 (fMP4) 并将它们逐块发送到客户端。我所做的是定义一个CHUNK_DURACTION_SEC
(以秒为单位的块持续时间)并计算一个块大小,如下所示:
有了这个,我对音频文件进行了分区,并且可以完全跳转chunkSize
到每个块的多个字节中获取它:
音频文件如何转换为 fMP4
这似乎适用于 Chrome 和 Firefox(到目前为止)。
如何附加块
在遵循这个例子之后,并意识到它根本不像这里解释的那样工作,我把它扔掉了,从头开始。不幸的是没有成功。它仍然无法正常工作。
以下代码应该从头到尾播放曲目。但是,我也需要能够寻求。到目前为止,这根本行不通。Seeking 将在seeking
事件触发后停止音频。
编码
运行它会给我以下输出:
为屏幕截图道歉,但不可能在没有 Chrome 中所有堆栈跟踪的情况下仅复制输出。
我也尝试过遵循这个例子并打电话sourceBuffer.abort()
,但这没有用。它看起来更像是几年前曾经使用过的 hack,但它仍然在文档中被引用(请参阅“示例”->“您可以在 Nick Desaulnier 的 bufferWhenNeeded 演示中看到类似的操作.. ”)。
尝试使用 MP3
我通过将曲目转换为 MP3 在 Chrome 下测试了上述代码:
并创建一个SourceBuffer
using audio/mpeg
as 类型:
我在寻找时遇到了同样的问题。
没有寻求的问题
上面的代码还有一个问题:
播放两分钟后,音频播放开始卡顿并过早停止。因此,音频播放到一定程度,然后在没有任何明显原因的情况下停止。
canplay
无论出于何种原因,还有另一个playing
事件。几秒钟后,音频停止了。
javascript - 使用 MP4box.js 和 onSegment 回调不调用 no websocket
所以我正在尝试使用 MP4Box.js。它在其自述页面上声明:它有一个演示:“一个执行即时碎片的播放器”。
然而,应该提供 MSE 的 onSegment 回调根本不会被调用:
现在把它放到一个 HTML 文件中会在 JavaScript 控制台中产生这个结果:
但之后什么也没有发生。为什么这里没有调用 onSegment?
ffmpeg - 如何从碎片化的mp4中获取帧信息
我正在使用以下命令生成 fmp4 文件
ffmpeg -rtsp_transport tcp -i rtsp://someuser:somepassword@somedomain:someport/Streaming/Channels/101 -acodec copy -vcodec copy -hls_segment_type fmp4 -hls_time 2 -hls_list_size 10 -hls_flags delete_segments+append_list+split_by_time -hls_playlist_type event test.m3u8
我需要知道每个片段的确切持续时间和帧数。不幸的是 -vstats 似乎被忽略了。
我尝试使用
ffprobe -show_frames ./test0.m4s
但我明白了
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fb68e80b000] could not find corresponding track id 1 [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fb68e80b000] could not find corresponding trex (id 1) [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fb68e80b000] could not find corresponding track id 0 [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fb68e80b000] trun track id unknown, no tfhd was found [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fb68e80b000] error reading header ./test0.m4s: Invalid data found when processing input
我假设这是因为尚未加载初始化段,但我找不到这样做的选项。
如果我尝试用
ffprobe -show_frames ./init.mp4
我没有得到任何帧信息和错误
Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 2560x1440): unspecified pixel format Consider increasing the value for the 'analyzeduration' and 'probesize' options
将不胜感激任何帮助。
video - 音频响度元数据
Apple 的 HLS 流验证器给了我这个警告:
我想编写一个测试来检查响度信息是否存在。我找不到用于提供此信息的元数据密钥,以便我可以检查它们。
如何确定响度归一化信息是否与使用 ffprobe 或 ffmpeg 的特定 mp4 文件一起提供?
video - 使用 GCP Transcoder API 进行转码会导致时间间隔
我一直在尝试 GCP 的Transcoder API并且在某些情况下随机变得比指定的时间更短时遇到了麻烦。
具体情况如下:
- 指定
startTimeOffset
和endTimeOffset
(在视频前后截断2秒) - fMP4 用作容器
- 输入视频是 mp4 并在 iPad Pro 上进行屏幕录制
例如,如果我不指定startTimeOffset
and endTimeOffset
,则时间不会缩短。此外,当为容器指定 MPEG2-TS 时也没有问题。视频本身可能有问题,但我还没有找到如何设置的线索。
我不确定这是 Transcoder API 的问题还是我的问题。
测试输入视频:https ://gofile.io/d/DUT9rr
以下是生成的清单文件的 ffprobe,比指定的短 2 秒。(预期:00:02:47.00
,实际:)00:02:45.00
在这种情况下,它是 2 秒的间隙,但可以是 10 秒或 30 秒,并且因视频而异。
以下是为 h264 + MPEG2-TS + Apple HLS 指定的时间。
google-chrome - Chrome 的 MediaRecorder 为每个关键帧生成新的 SPS 和 PPS
我正在尝试使用 MIME 类型video/webm;codecs="avc1.42C01E"
和 avc1 的其他变体对 MediaRecorder 的 webm 输出进行转箱。我想生成video/mp4;codecs="avc1.42C01E"
包含相同视频有效负载的 MIME 类型的分段 mp4。(为了延迟和功率,我希望避免对视频有效负载进行转码。)这是可行的,除了一个问题。
每个关键帧的数据流——每个 webm 集群有效负载中的第一个 SimpleBlock——都以 SPS 和 PPS NALU 开头。没关系,除了一件事。
pic_parameter_set_id
每个关键帧的新 SPS 和 PPS NALU 具有和的新值seq_parameter_set_id
。第一个关键帧的pic_parameter_set_id
值为 0,后续关键帧的值为 1、2、3,依此类推。当它达到 56 时,它会循环回到 0。(57 个不同的值?)
类似地,该seq_parameter_set_id
值从 0 变为 31 并循环返回。
更重要的是,每对新的 SPS 和 PPS 之后的切片 NALU 都引用了新pic_parameter_set_id
值。
由于以下几个原因,这是有问题的:
- 这些 id 值使用 exp-Golomb 编码进行编码。这种编码使用更多位来编码更大的数字。因此,其中一个 MediaRecorder 会话运行的时间越长,数据结构就越大:PPS、SPS 和切片数据。
- MP4 (Quicktime) 在“avcC”原子中携带编解码器专用数据。它应该包括文件的 SPS 和 PPS NALU。但是,如果这些 NALU 对每个关键帧都发生变化,则很难生成有用的“avcC”。
因此,SourceBuffer.appendBuffer()
使用 MSE 播放这些 fmp4 数据流的方法会在接收到第二个关键帧时冻结其图像。
有没有办法抑制或解决 MediaRecorder 生成的 H264 媒体中这些不断变化的参数集 id,因此整个会话使用相同的 SPS 和 PPS?
node.js - 串流并保存
我有一个 mp4 视频流进来,我想将它保存到磁盘,但我也想在它完成之前将已保存到磁盘的数据流式传输,以便我可以同时观看和保存。我目前的方法是将流传输到磁盘并从磁盘创建一个读取流,然后发送,但目前它只是加载一点然后停止。
这是我当前的代码
mp4 - 检测 h264 流中的 I 帧(分段 mp4)
我需要检查 H264 流中的第一帧是 I 帧。
在输入上,我有零碎的 mp4 文件。我试图在 moof->traf->trun "Sample depends on" 标志中找到框架类型。但似乎并不是每个容器都填充了这个标志。所以我想尝试用原始数据确定 mdat 块中的帧类型。
我只需要检查每个片段中的第一帧是 I 帧。关于其他帧的信息无关紧要。
我该怎么做?