精易论坛

标题: 取MP4帧宽度和帧高度_W版(支持大文件) [打印本页]

作者: simor3    时间: 2022-3-29 12:27
标题: 取MP4帧宽度和帧高度_W版(支持大文件)
[2021开源大赛(第六届)] [分享源码] 取MP4帧宽度和帧高度(本地)
https://125.confly.eu.org/forum.php?mod=viewthread&tid=14707085
[易源码分享] [分享源码] 文件读写W版
https://125.confly.eu.org/forum.php?mod=viewthread&tid=14219684

之前取mp4的宽高是用的mediainfo.dll,因为取出的是所有元信息,所以我觉得取出的速度有点慢,我想找个取出快一点的方法。
去年番茄吧发了一个取MP4帧宽度和帧高度的帖子,我测试了一下,有几个问题:
1.不支持unicode路径。
2.不支持大文件。
3.由于mp4的编码方式也是五花八门,所以那个源码有一些mp4取不出来。

我根据那个源码,修复了以上的几个问题,源码如下。
其中支持的unicode路径和大文件读写是用的福仔的文件读写W版。
但是他这个W版也有一些问题,取文件长度和移动读写位置也就是GetFileSize和SetFilePointer没有采用EX版本,导致不能取和移动到长整数,
所以各位自己把这个文件读写W版里的GetFileSize和SetFilePointer替换成GetFileSizeEX和SetFilePointerEX就行了。
下面的_un命令就是修改了的福仔的文件读写W版。

关于定位mp4的“thkd”这个位置,由于对mp4格式研究不深,只知道这个thkd有时候在文件头,
有时候在文件尾,在文件尾的时候,具体在哪个位置,没法定位,只能用笨办法取文件尾的25000000字节,然后再搜索。
这样导致的问题就是读入这么一块字节集再搜索,速度就又慢下来了,所以如果遇到"thkd"在文件尾的,速度大概300ms/文件。
好在一些短视频的标准MP4文件,信息都在文件头,取出速度就会很快,十几ms左右。
这个源码只能取mp4,如果要取其他格式,还需要再研究,但是我觉得没必要,还是直接用mediainfo.dll方便,哈哈。
这是我研究的关于取mp4宽高的过程,虽然最后感觉没用上,但从研究的过程中也学到的很多东西,顺便也解决了福仔那个文件读写W版里的一些小问题。

  
子程序名返回值类型公开备 注
取MP4帧高度文本型 
参数名类 型参考可空数组备 注
MP4文件字节集
变量名类 型静态数组备 注
文件号整数型 
index长整数型 
读写位置长整数型 
bin字节集 
帧宽度长整数型 
帧高度长整数型 
文件号 = 打开文件_un (MP4文件, #读入, #无限制 )
bin = 读入字节集_un (文件号, 1000)
index = 寻找字节集 (bin, { 0, 0, 0, 92, 116, 107, 104, 100 }, )
如果真 (index = -1)
index = 寻找字节集 (bin, 到字节集 (“free”), )
如果真 (index = -1)
读写位置 = 取文件长度_un (文件号) - 25000000
移动读写位置_un (文件号, #文件首, 读写位置)
bin = 读入字节集_un (文件号, 25000000)
index = 寻找字节集 (bin, { 0, 0, 0, 92, 116, 107, 104, 100 }, )
帧宽度 = 字节集转长整数 (取字节集中间 (bin, index + 84, 2))
帧高度 = 字节集转长整数 (取字节集中间 (bin, index + 88, 2))
如果真 (帧宽度 = 0 帧高度 = 0)
index = 寻找字节集 (bin, { 0, 0, 0, 92, 116, 107, 104, 100 }, index + 4)
帧宽度 = 字节集转长整数 (取字节集中间 (bin, index + 84, 2))
帧高度 = 字节集转长整数 (取字节集中间 (bin, index + 88, 2))
返回 (到文本 (帧宽度)“×”到文本 (帧高度))
index = index + 4
读写位置 = 字节集转长整数 (取字节集中间 (bin, index, 4))
移动读写位置_un (文件号, #文件首, 读写位置)
bin = 读入字节集_un (文件号, 500)
index = 寻找字节集 (bin, { 0, 0, 0, 92, 116, 107, 104, 100 }, )
帧宽度 = 字节集转长整数 (取字节集中间 (bin, index + 84, 2))
帧高度 = 字节集转长整数 (取字节集中间 (bin, index + 88, 2))
如果真 (帧宽度 = 0 帧高度 = 0)
如果 (取文件长度_un (文件号) - 读写位置 - 300 < 25000000)
移动读写位置_un (文件号, #文件首, 读写位置 + 300)
bin = 读入字节集_un (文件号, 取文件长度_un (文件号) - 读写位置 - 300)
index = 寻找字节集 (bin, { 0, 0, 0, 92, 116, 107, 104, 100 }, )
帧宽度 = 字节集转长整数 (取字节集中间 (bin, index + 84, 2))
帧高度 = 字节集转长整数 (取字节集中间 (bin, index + 88, 2))
读写位置 = 取文件长度_un (文件号) - 25000000
移动读写位置_un (文件号, #文件首, 读写位置)
bin = 读入字节集_un (文件号, 25000000)
index = 寻找字节集 (bin, { 0, 0, 0, 92, 116, 107, 104, 100 }, )
帧宽度 = 字节集转长整数 (取字节集中间 (bin, index + 84, 2))
帧高度 = 字节集转长整数 (取字节集中间 (bin, index + 88, 2))

关闭文件_un (文件号)
返回 (到文本 (帧宽度)“×”到文本 (帧高度))



作者: 不苦小和尚    时间: 2022-3-29 14:37
有时候会用到,发下源码啊
作者: hadisi    时间: 2022-3-29 15:37
感谢分享。
作者: wuqingg    时间: 2022-3-29 15:41
厉害啊,那么怎么取出第一帧呢?
作者: simor3    时间: 2022-3-29 16:02
wuqingg 发表于 2022-3-29 15:41
厉害啊,那么怎么取出第一帧呢?

调用ffmpeg
作者: Azumarill    时间: 2022-3-29 16:25
好东西,需要支持下
作者: kentfung    时间: 2022-3-29 16:42
mediainfo不香吗??
作者: 杨明煜    时间: 2022-3-29 20:42
支持一下,谢谢!......
作者: 深圳梦    时间: 2022-3-29 20:55
新技能已get√
作者: 番茄吧    时间: 2022-3-30 10:07
还有人深研究,好评下,我当初就是为了解决问答区的易友的问题,临时研究了一下,挺好!!
作者: simor3    时间: 2022-3-30 12:02
番茄吧 发表于 2022-3-30 10:07
还有人深研究,好评下,我当初就是为了解决问答区的易友的问题,临时研究了一下,挺好!! ...

非常感谢大佬的原贴代码给了我思路,不然真没头绪研究这个
作者: sol9702    时间: 2022-3-30 13:57
楼主,这个只能取MP4的吗?其他视频格式不可以啊?
作者: 噼里啪啦咻    时间: 2022-3-30 13:59
666666666666666666666666
作者: simor3    时间: 2022-3-30 17:02
sol9702 发表于 2022-3-30 13:57
楼主,这个只能取MP4的吗?其他视频格式不可以啊?

其他的不行,标识符不一样,需要单独处理。
作者: 网络注册网员    时间: 2024-4-30 12:08
非常感谢
作者: xmm    时间: 2024-7-8 04:28
感谢分享,很给力!~




欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4