python-3.x - 在python中生成特定大小(以MB为单位)的空白mp4视频

标签 python-3.x ffmpeg moviepy

我想生成一个特定大小的空白(黑白,内容无关紧要)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/

相关文章:

python - __sizeof__ 没有被 sys.getsizeof 调用

python - 使用 Python 使用特定关键字解析 JSON

node.js - NodeJS 创建一个像 youtube 视频一样的故事书?

ffmpeg - 为什么将帧速率加倍会产生不一致的帧?

python - 为什么 moviepy 在生成音频文件时提示比特率?

python - 如何从一个表中删除所有出现的数字,并从另一个表中查找数字?

python-3.x - 将变量写入文件

video - FFmpeg 命令为 mpg2、mss、lxf、3g2 视频文件添加文本水印

python - 从视频文件中提取的音频太大

python - 无法在 Moviepy 中添加文本剪辑。获取与 Imagemagic 相关的错误