【问题标题】:Generate blank mp4 video of a specific size (in MB) in python在python中生成特定大小(以MB为单位)的空白mp4视频
【发布时间】:2020-04-08 01:38:21
【问题描述】:

我想生成一个特定大小的空白(黑色、白色、内容无关)MP4 视频,例如 50 MB。如何在 python 中或使用任何其他工具执行此操作?

我已经四处搜索,但只获得了代码 sn-ps 来生成特定尺寸的视频。

【问题讨论】:

    标签: python-3.x ffmpeg moviepy


    【解决方案1】:

    您可以创建一个较短的文件并在文件末尾添加零填充。

    关键是将“moov atom”放在文件的开头。

    • 使用 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 时长 5 秒的 MP4 文件:

    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。

    【讨论】:

    • 我将如何强制执行持续时间?假设我需要一个持续时间为 5 秒的 50 MB 文件?我尝试添加持续时间标签,但没有这样做。
    • 50MB 5 秒太大。 50MB 50 秒也许是可能的。编码器使用选定的比特率作为上限。您需要对压缩不充分的随机内容进行编码。零填充也可以工作。你能说出你需要它做什么吗?为什么是mp4?为什么是 50MB?
    • @Rotem:我创建了一个只能提供 5s、10s 和 15s 视频的视频服务器。 5s 视频的最大大小为 50 MB。 Mp4 因为定制的媒体播放器只允许播放 mp4 视频格式。这一切都在项目要求中。我可以对压缩不充分的随机内容进行编码。我们该怎么做?
    • 视频编解码器有什么限制吗?帧率?分辨率?
    • 我更新了我的帖子 - 创建 50MB 的 MP4 文件,持续时间为 5 秒。
    【解决方案2】:

    如果您提供正确的比特率和持续时间,您可以接近 50 MB。对于 5 秒的持续时间和 ~50 MB 的文件大小:

    ffmpeg -f lavfi -i color=size=1280x720:duration=5 -c:v libx264 -x264-params "nal-hrd=cbr" -b:v 81920k -minrate 81920k -maxrate 81920k -bufsize 81920k -movflags +faststart video.mp4
    

    注意:bitrate = file size / duration,bitrate 相关选项以bits 为单位,会有一些小的复用开销。这不会是准确的。

    如果 ~50MB 足够好,这就是您需要做的所有事情。

    【讨论】:

    • dd 步骤会导致数据包损坏。
    • @llogan:我将如何强制执行持续时间?假设我需要一个持续时间为 5 秒的 50 MB 文件?根据您的公式,我调整了文件大小(尺寸),但并没有真正做到。
    • @Gyan 我认为是这样,但通过一些懒惰的测试它工作得很好。
    • @user248884 查看新示例。使用duration 设置所需的持续时间并计算适当的比特率(比特率 = 文件大小/持续时间)以大致匹配所需的输出文件大小。如果您需要帮助获取比特率值,请搜索“比特率计算器”。
    猜你喜欢
    • 2019-03-16
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多