VLC 视频流视频无法工作,因为它保存为损坏的视频

问题描述 投票:0回答:1

我已经使用 VLC 流录制了视频。录音结束后,我点击了停止按钮,几秒钟内就关闭了播放器。现在视频无法播放我以前使用过此功能并且效果很好。

由于播放器快速关闭,我认为视频现在无法播放。 我检查了编解码器详细信息,发现它丢失了。可用的视频具有 H264 - MPEG-4 VAC。

有什么办法可以解决这个问题吗?我已附上可播放视频和当前视频的详细信息。a video taken from the same way and the current video

操作系统 - Windows 11

我尝试使用 vlc 将视频转换为 avi 格式,但它没有开始转换。 我已尝试更新播放器,但它是最新版本。

video-streaming mp4 vlc video-editing
1个回答
0
投票

首先检查以下工具是否会显示您的第一帧(仅适用于 VLC 录制 @ 720p)

工具:预览损坏的 MP4 中的第一帧

如果是,那么您的 MP4 的结构如下(显示前 64 个字节):

00 00 00 18 66 74 79 70 69 73 6F 6D 00 00 00 00     ....ftypisom....
6D 70 34 31 61 76 63 31 00 00 00 00 6D 64 61 74     mp41avc1....mdat
00 00 00 00 00 00 00 00 00 00 02 B0 06 05 FF FF     ...........°..ÿÿ
AC DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE     ¬ÜEé½æÙH·–,Ø Ù#î

地点:
左侧是您的字节(写为十六进制字符)。
右侧是解码后的UTF-8文本(如果可以解码)。

在处理文件字节时始终使用十六进制编辑器进行双重检查

通过研究,您将了解到 MP4 文件分为两个主要部分。有

moov
保存元数据(解码器设置以及每帧的字节位置等所需)。另一部分是
mdat
,该部分保存原始音频/视频字节。

损坏的 VLC 录音(MP4)仅包含

mdat
部分。

修复为MP4

要修复,您可以使用现有的 MP4 来了解所需的“原子”并将它们复制到新的(修复的)字节集中。您需要编辑名为 Sample Table 的部分(在文件中查找

stbl
)并更新这些详细信息(哪些帧是关键帧?哪些字节位置?帧的哪些时间戳?等等)。

更多信息:MP4 Atom 解析 - 如何配置时间

修复为H.264

最简单的修复方法是尝试从 MP4 中手动提取 H.264 帧,然后使用 FFmpeg(或 VLC)将这些视频帧与之前提取的音频(通过使用修复软件)组合起来。

要提取视频帧,您需要循环遍历 MP4 内的块(称为 NAL 单元)。

您的第一个 NALU(类型为 SEI)位于 44 的位置(也称为偏移量)。从该字节位置,您可以向后退 4 个字节,然后从新位置开始,您现在可以通过读取这 4 个字节来获取 NALU 的长度(作为一个 32 位无符号整数,它是无符号的,因为我们不这样做)不要期望看到任何负号,只会返回一个正数)。

我将添加一些实用函数来帮助您入门:

要从数组中的某个位置读取 4 字节值:

function read_UInt32_BE_in_Array( in_array, startPos )
{
    return ( (in_array[ startPos+0 ]) << 24 | (in_array[ startPos+1 ]) << 16 | (in_array[ startPos+2 ]) << 8 | (in_array[ startPos+3 ]) );
}

将 4 字节值写入数组中的某个位置:

function write_UInt32_BE_in_Array( in_val, in_array, startPos )
{
    in_array[ startPos+0 ] = ( (in_val >> 24) & 0x000000FF );
    in_array[ startPos+1 ] = ( (in_val >> 16) & 0x000000FF );
    in_array[ startPos+2 ] = ( (in_val >>  8) & 0x000000FF );
    in_array[ startPos+3 ] = ( (in_val >>  0) & 0x000000FF );
}

过程(伪代码):

myCurrentPos = 44; //# start of SEI data
type_NALU = myBytes[ myCurrentPos ]; //# check NALU type, should be a 6 if SEI data
sizePos = (myCurrentPos - 4); //# go back -4 steps to reach "size" bytes
sizeNum = read_32bit_BigEndian_at_Pos( sizePos ); //# read the 4 size bytes (in Big Endian format)

//# copy bytes (Array slots) from offset "myCurrentPos" up to position of +"sizeNum".

//# skip to next frame
myCurrentPos = ( sizeNum + 4 )
type_NALU = myBytes[ myCurrentPos ]; //# check NALU type, should be a 5 if Keyframe data.

//# repeat process of re-reading "sizeNum" and then copy by this length.
  • 仅复制 NALU 类型(十六进制):0665414243(或相同的十进制:6、101、65、66、67)。
  • 复制意味着将提取的字节值写入新的输出数组

在输出数组中(每帧)...

  • 首先四个字节:
    00 00 00 01
    。 (为新数据创建 H264 起始代码)
  • 然后粘贴您复制的“块”字节。
  • 重复另一帧直至结束。

最后将输出文件保存为

test.h264
并尝试在媒体播放器中播放。
接下来使用 FFmpeg 或 VLC 将 H264 视频文件与提取的 MP3 数据合并。

© www.soinside.com 2019 - 2024. All rights reserved.