代码示例:
import struct
import os
from loguru import logger
# 支持文件类型
# 用16进制字符串的目的是可以知道文件头是多少字节
# 各种文件头的长度不一样,少半2字符,长则8字符
def typeList():
"""获取文件格式十六进制码表"""
return {
"68746D6C3E": 'html',
# "d0cf11e0a1b11ae10000":'xls',
"44656C69766572792D64": 'eml',
'ffd8ffe000104a464946': 'jpg',
'89504e470d0a1a0a0000': 'png',
'47494638396126026f01': 'gif',
'49492a00227105008037': 'tif',
'424d228c010000000000': 'bmp',
'424d8240090000000000': 'bmp',
'424d8e1b030000000000': 'bmp',
'41433130313500000000': 'dwg',
'3c21444f435459504520': 'html',
'3c21646f637479706520': 'htm',
'48544d4c207b0d0a0942': 'css',
'696b2e71623d696b2e71': 'js',
'7b5c727466315c616e73': 'rtf',
'38425053000100000000': 'psd',
'46726f6d3a203d3f6762': 'eml',
# 'd0cf11e0a1b11ae10000':'doc',
# 'd0cf11e0a1b11ae10000':'vsd',
'5374616E64617264204A': 'mdb',
'252150532D41646F6265': 'ps',
'255044462d312e350d0a': 'pdf',
'2e524d46000000120001': 'rmvb',
'464c5601050000000900': 'flv',
'00000020667479706d70': 'mp4',
'49443303000000002176': 'mp3',
'000001ba210001000180': 'mpg',
'3026b2758e66cf11a6d9': 'wmv',
'52494646e27807005741': 'wav',
'52494646d07d60074156': 'avi',
'4d546864000000060001': 'mid',
'504b0304140000080044': 'zip',
'504b03040a0000080000': 'zip',
# '504b03040a0000000000':'zip',
'526172211a0700cf9073': 'rar',
'235468697320636f6e66': 'ini',
'504b03040a0000000000': 'jar',
'4d5a9000030000000400': 'exe',
'3c25402070616765206c': 'jsp',
'4d616e69666573742d56': 'mf',
'3c3f786d6c2076657273': 'xml',
'494e5345525420494e54': 'sql',
'7061636b616765207765': 'java',
'406563686f206f66660d': 'bat',
'1f8b0800000000000000': 'gz',
'6c6f67346a2e726f6f74': 'properties',
'cafebabe0000002e0041': 'class',
'49545346030000006000': 'chm',
'04000000010000001300': 'mxp',
'504b0304140006000800': 'docx',
'd0cf11e0a1b11ae10000': 'wps',
'6431303a637265617465': 'torrent',
}
# 字节码转16进制字符串
def bytes2hex(bytes):
logger.info('字节码转16进制字符串-关键码转码……')
num = len(bytes)
hexstr = u""
for i in range(num):
t = u"%x" % bytes[i]
if len(t) % 2:
hexstr += u"0"
hexstr += t
return hexstr.upper()
# 获取文件类型
def filetype(filename):
logger.info('读文件二进制码……')
# 二进制读取,提取关键码
with open(filename, 'rb') as f:
bins = f.read(20) # 提取20个字符
bins = bytes2hex(bins) # 转码
bins = bins.lower() # 小写
logger.info(f"bins = {bins}")
logger.info('获取文件格式十六进制码表……')
tl = typeList() # 文件类型
ftype = 'unknown'
logger.info('关键码比对中……')
for hcode in tl.keys():
lens = len(hcode) # 需要的长度
if bins[0:lens] == hcode:
ftype = tl[hcode]
break
if ftype == 'unknown': # 全码未找到,优化处理,码表取5位验证
bins = bins[0:5]
for hcode in tl.keys():
if len(hcode) > 5 and bins == hcode[0:5]:
ftype = tl[hcode]
break
return ftype
def test_ffprobe(origin_full_save_path):
# test
output = os.popen(f'ffprobe -print_format json -show_streams {origin_full_save_path}')
output_str = output.read()
logger.info(f"res = {type(output_str)} | {output_str}")
output_dic = eval(output_str)
logger.info(f"res = {type(output_dic)} | {output_dic}")
for key, val in output_dic.items():
for streams_dic in val:
codec_type = streams_dic.get('codec_type')
codec_name = streams_dic.get('codec_name')
logger.info(f"codec_name = {codec_name} | codec_type = {codec_type}")
# test
if __name__ == '__main__':
# ftype = filetype('./cat.gif')
# ftype = filetype('./1format.zip')
# ftype = filetype('./30-zhen.mp3')
# ftype = filetype('./test_file/aac_2_wav_audio_2EcdAD0379C1.wav')
# ftype = filetype('./test_file/秦PLUS DM-i配音.mp3')
# ftype = filetype('./test_file/mp4-2-mp3-wav-audio_1da96F2273c4.wav')
# ftype = filetype('./test_file/苏州街11分钟.m4a')
# logger.info(f"ftype = {ftype}")
#
test_ffprobe('./test_file/30-zhen.mp3')
需要使用ffprobe,需要安装ffmpeg配合使用
在 Mac OSX 上使用 Homebrew 安装 ffmpeg:
brew install ffmpeg
brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-libass --with-libquvi --with-libvorbis --with-libvpx --with-opus --with-x265
brew update && brew upgrade ffmpeg
将视频 MP4 转化为 GIF
ffmpeg -i small.mp4 small.gif
转化视频中的一部分为 GIF
ffmpeg -t 3 -ss 00:00:02 -i small.webm small-clip.gif
从视频中第二秒开始,截取时长为3秒的片段转化为 gif
转化高质量 GIF
默认转化是中等质量模式,若要转化出高质量的 gif,可以修改比特率
ffmpeg -i small.mp4 -b 2048k small.gif
视频属性调整
缩放视频尺寸
ffmpeg -i big.mov -vf scale=360:-1 small.mov
注意 sacle
值必须是偶数,这里的 -1
表示保持长宽比,根据宽度值自适应高度。
如果要求压缩出来的视频尺寸长宽都保持为偶数,可以使用 -2
加倍速播放视频
ffmpeg -i input.mov -filter:v "setpts=0.5*PTS" output.mov
定义帧率 16fps:
ffmpeg -i input.mov -r 16 -filter:v "setpts=0.125*PTS" -an output.mov
慢倍速播放视频
ffmpeg -i input.mov -filter:v "setpts=2.0*PTS" output.mov
静音视频(移除视频中的音频)
ffmpeg -i input.mov -an mute-output.mov
-an
就是禁止音频输出
将 GIF 转化为 MP4
ffmpeg -f gif -i animation.gif animation.mp4
也可以将 gif 转为其他视频格式
ffmpeg -f gif -i animation.gif animation.mpeg
ffmpeg -f gif -i animation.gif animation.webm
获取 GIF 的第一帧图片
使用 ImageMagick 可以方便第提取 gif 图片的第 N 帧图像。
安装 ImageMagick
brew install imagemagick
提取第一帧
convert 'animation.gif[0]' animation-first-frame.gif
通过 [0]
就可以提取出 gif 的第一帧图像。
GIF 转出来的 MP4 播放不了?
有些 GIF 转化出来的 MP4 不能被 Mac QuickTime Player.app 播放,需要添加 pixel formal
参数
ffmpeg -i input.gif -vf scale=420:-2,format=yuv420p out.mp4
使用 yunv420p
需要保证长宽为偶数,这里同时使用了 scale=420:-2
。