我想生成一个特定大小的空白(黑白,内容无关紧要)MP4 视频,例如 50 MB。我如何在 python 中或使用任何其他工具执行此操作?
我四处搜索,但只得到了生成特定尺寸视频的代码片段。
最佳答案
您可以创建一个较短的文件并在文件末尾添加零填充。
关键是将“moovatom”放在文件的开头。
使用 FFmpeg 生成合成(灰色)视频:
ffmpeg -y -f lavfi -i testsrc=size=1920x1080:rate=1 -vf hue=s=0 -vcodec libx264 -preset superfast -tune zerolatency -pix_fmt yuv420p -t 1000 -movflags +faststart vid.mp4
您可以使用Python子进程模块:
sp.run('ffmpeg -y -f lavfi -i testsrc=size=1920x1080:rate=1 -vf hue=s=0 -vcodec libx264 -preset superfast -tune zerolatency -pix_fmt yuv420p -t 1000 -movflags +faststart vid.mp4')
在文件末尾添加零,使文件大小恰好为 50 MB。
这是Python代码:
import subprocess as sp
import os
# Generate synthetic pattern.
# Make the pattern gray: https://davidwalsh.name/convert-video-grayscale
# Place the moov atom at the beginning of the file: https://superuser.com/questions/606653/ffmpeg-converting-media-type-aswell-as-relocating-moov-atom
# Use superfast preset and tune zerolatency for all frames to be key frames https://lists.ffmpeg.org/pipermail/ffmpeg-user/2016-January/030127.html (not a must)
# Make the file much smaller than 50MB.
sp.run('ffmpeg -y -f lavfi -i testsrc=size=1920x1080:rate=1 -vf hue=s=0 -vcodec libx264 -preset superfast -tune zerolatency -pix_fmt yuv420p -t 1000 -movflags +faststart vid.mp4')
# Add zero padding to the end of the file
# https://stackoverflow.com/questions/12768026/write-zeros-to-file-blocks
stat = os.stat('vid.mp4')
with open('vid.mp4', 'r+') as of:
of.seek(0, os.SEEK_END)
of.write('\0' * (50*1024*1024 - stat.st_size))
of.flush()
如果您希望文件大小约为 50MB,您可以设置比特率和时间。
以位为单位的大小将是比特率*时间。
请参阅How to force Constant Bit Rate using FFMPEG
注意:测试模式有一个小问题 - 它太“可压缩”,因此我们需要设置一个非常小的比特率。
以下是创建大约 1MB MP4 文件的示例 (10kbit*1024*800/8 = 1MB
):
ffmpeg -y -f lavfi -i testsrc=size=3840x2160:rate=1 -vf hue=s=0 -vcodec libx264 -tune zerolatency -b:v 10k -minrate 10k -maxrate 10k -t 800 -movflags +faststart -bufsize 1024k vid.mp4
更新:
生成 50MB MP4 文件,持续时间 5 秒:
5 秒的 50MB 大小需要大约80,000,000 bis/sec
的比特率。
由于码率非常高,我们需要使用高分辨率、高帧率的输入帧。
我们还需要确保视频帧没有被很好地压缩。
建议使用随机输入图像,因为随机数据很难压缩。
以下 Python 代码构建 300 个分辨率为 1920x1080 的随机图像,并使用 FFmpeg 将图像序列编码为 MP4 视频文件:
import numpy as np
import cv2
import subprocess as sp
import os
# Build random input files (set of Tiff images).
# Use random data
# Use Full HD video frames at 60Hz
width, height, fps = 1920, 1080, 60
# Video duration in seconds
n_seconds = 5
for i in range (n_seconds*fps):
# Random gray image in resolution width by height.
img = np.random.randint(0, 255, (height, width), np.uint8)
# Images sequance file names (about 1GBytes of disk space):
# 00000.tif, 00001.tif, 00002.tif, 00003.tif... 00299.tif
cv2.imwrite(str(i).zfill(5)+'.tif', img)
# Destination file size is 50MBytes.
file_size_in_bytes = 50*1024*1024
# Desired bitrate is 83886080*0.90 bits/second
# Multiply by 0.9 - Leave 10% for the headers.
bitrate = int(round(file_size_in_bytes*8*0.9 / n_seconds))
# Encode video from the sequence of random images (use H.264 video codec).
# Set the video bitrate to 75497472.
# Set buffer size to 75497472*10 (not too tight) If we specify a smaller -bufsize, ffmpeg will more frequently check for the output bit rate and constrain it... https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
sp.run('ffmpeg -y -r {} -i %05d.tif -vcodec libx264 -tune zerolatency -b:v {} -minrate {} -maxrate {} -movflags +faststart -bufsize {} vid.mp4'.format(fps, bitrate, bitrate, bitrate, bitrate*10))
vid.mp4
的大小非常接近 50MB。
关于python-3.x - 在python中生成特定大小(以MB为单位)的空白mp4视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61066926/