基于FFmpeg的B站视频下载处理

发布于:2025-08-11 ⋅ 阅读:(10) ⋅ 点赞:(0)

起因是这样的

一天,本人在B站客户端缓存了一个视频,用于学习参考等学术交流,但是视频和音频却是分开且通过Win Hex查看发现文件头含有9个“30”,想到一个个手动删字节不如让程序取代,便有了本文章

这一篇文章发布之前,其实早在5个月以前就完成了代码

代码流程

不同语言可以参考流程来做(本教程介绍Console版本的单文件处理)

1、获取ffmpeg的路径

如题,我们首先需要ffmpeg,可以去网上随便什么地方下一个编译好的ffmpeg放在程序文件夹下,然后获取ffmpeg的路径

Dim ff As String = Path.GetDirectoryName(Process.GetCurrentProcess.MainModule.FileName) & "\ffmpeg.exe"

2、获取 想要处理的 文件

Console.WriteLine("输入要转换的文件路径:")
Dim arg As String
arg = Console.ReadLine

If IO.File.Exists(arg) = False Then
    Console.WriteLine("文件不存在!")
    Continue Do
End If

Dim f As New FileStream(arg, FileMode.Open)

3、定义音频和视频判定字节

(这里说明一下,绝大部分B站客户端下载的视频是mpg格式的视频,文件内部二进制数据会包含Video或Sound等字符来标记是视频还是音频,但是少部分格式不清楚,因此本程序保留了未知格式,可以降低错判率)

Dim vid As Byte() = {&H56, &H69, &H64, &H65, &H6F}
Dim sod As Byte() = {&H53, &H6F, &H75, &H6E, &H64}

Dim flag As Boolean = False
f.Position = 0

For i = 0 To f.Length - 1
    Dim buf = f.ReadByte
    Dim array1(3) As Byte

    If buf = &H53 Then
        f.Read(array1, 0, 4)
        If CompareByte(sod, sod(0), array1) Then
            Console.WriteLine("此文件是音频,输入""/""以重新输入")
            flag = True
            Exit For
        End If
    ElseIf buf = &H56 Then 'If buf(0) = &H56 Then
        f.Read(array1, 0, 4)
        If CompareByte(vid, vid(0), array1) Then
            Console.WriteLine("此文件是视频,输入""/""以重新输入")
            flag = True
            Exit For
        End If
    End If
Next

If flag = False Then
    Console.WriteLine("输入的格式可能不准确,除非你知道你自己在做什么!输入""/""以重新输入")
End If

匹配字节

Function CompareByte(OriginalByte As Byte(), firstByte As Byte, LastBytes As Byte())
    If firstByte = OriginalByte(0) Then
        For i = 0 To LastBytes.Count - 1
            If LastBytes(i) <> OriginalByte(i + 1) Then
                Return False
            End If
        Next
        Return True
    Else
        Return False
    End If
End Function

这里解释下为何要使用这一种方法来匹配文件类型……

因为如果你直接读取所有的音频文件到内存再转成Array,且不说上限有多少,代码会比这个复杂,而且占用大量系统资源,小一点的音频还好,如果是4K视频,内存都要炸翻天。

所以我们使用字节流的方式,f.ReadByte一次,字节读取位置就+1,但凡匹配到0x56,0x53的就开始匹配后面4位是否一致,如果一致了,就按对应格式告诉用户这个是视频还是音频。

4、让用户输入转换后的名称

f.Position = 0
Console.WriteLine("输入转换后文件名称,新文件保存于原文件同一个目录下,请加上后缀!例如as.mp4")

Dim newfname As String
newfname = Console.ReadLine
If newfname = "/" Then
    Continue Do
End If
Dim newpath As String = Path.GetDirectoryName(arg) & "\" & newfname
Dim w As New FileStream(newpath, FileMode.Create)

Dim count As Integer = f.Length

5、询问用户删多少个字节

一般客户端为9个,UWP(不支持版本)是3个而且音视频合体

Console.WriteLine("输入删除视频前多少个byte,建议查看WinHex")
Dim start As Integer = CInt(Console.ReadLine())

For i = 0 To start - 1
    f.ReadByte()
Next

For i = 0 To count - start - 1
    w.WriteByte(f.ReadByte)
Next
w.Close()
f.Close()

Process.Start(ff, "-i " & newfname & " " & newpath)

Console.WriteLine("转换成功!")

错误处理就不做了,获取ffmpeg的数据流太麻烦了

敬告

注意,此方法仅用于学习和参考,请勿用于非法用途!!!


网站公告

今日签到

点亮在社区的每一天
去签到