Создать пустое видео mp4 с указанным размером c (в МБ) в python - PullRequest
1 голос
/ 06 апреля 2020

Я хочу создать пустое (чёрное, белое, содержимое не имеет значения) MP4-видео определенного c размера, скажем, 50 МБ. Как мне сделать это в python или с помощью любого другого инструмента?

Я искал вокруг, но получил только фрагменты кода для создания видео с определенными c размерами.

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Вы можете создать более короткий файл и добавить нулевое заполнение в конец файла.

Ключ должен поместить «атом moov» в начало файла.

  • Создание синтезированного c (серого) видео с использованием 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 МБ.

Вот код 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()

Если вы хотите, чтобы размер файла составлял приблизительно 50 МБ, вы можете установить битрейт и время.
Размер в битах будет битрейт * время.
См. Как принудительно установить постоянную скорость передачи битов с помощью FFMPEG

Примечание: есть небольшая проблема с тестовый шаблон - он слишком «сжимаемый», поэтому нам нужно установить очень маленькую скорость передачи данных.

Вот пример создания файла MP4 размером приблизительно 1 МБ (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

Обновление:

Создание 50 МБ MP4-файла с продолжительностью 5 секунд:

Размер 50 МБ в течение 5 секунд требует битрейта около 80,000,000 bis/sec.
Поскольку битрейт очень высок, нам нужно использовать входной кадр с высоким разрешением и высокой частотой кадров.
Нам также нужно убедиться, что видеокадры не очень хорошо сжаты.
Рекомендуется случайный ввод изображений, потому что случайный данные трудно сжать.

Следующий код Python создает 300 случайных изображений в разрешении 1920x1080 и кодирует последовательность изображений в видеофайл MP4 с помощью FFmpeg:

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 очень близок до 50 МБ.

0 голосов
/ 07 апреля 2020

Вы можете приблизиться к 50 МБ, если вы предоставите правильный битрейт и длительность. Для длительности 5 секунд и размера файла ~ 50 МБ:

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

Примечание: битрейт = размер файла / длительность , битрейт параметры в битах, и будут некоторые незначительные накладные расходы. Это не будет точно.

Если ~ 50 МБ достаточно, это все, что вам нужно сделать.

...