como fazer o vídeo fora da seqüência de imagens, pulando todos os n arquivos

0

Eu sei como fazer um vídeo a partir de uma seqüência de imagens usando ffmpeg -i %0Xd.png ou *.png etc. Mas o que eu gostaria de fazer é de alguma forma dizer ao ffmpeg para pular todos os n arquivos. Por exemplo. Se eu tiver arquivos numerados 0000, 0001, 0002, 0003, 0004, 0005, 0006, etc. Eu gostaria de fazer um vídeo com os arquivos 0000, 0003, 0006, 0009 etc (ou seja, tendo cada n == arquivo 3). Mover e renomear não é realmente uma opção, já que tenho centenas de milhares de imagens e gostaria de converter em lote muitas versões diferentes com diferentes quantidades. por exemplo,

  • 0000, 0001, 0002 ... - > n1.mp4
  • 0000, 0002, 0004 ... - > n2.mp4
  • 0000, 0003, 0006 ... - > n3.mp4

etc.

Isso é possível?

    
por memo 03.03.2018 / 12:35

1 resposta

1

Acabei escrevendo um script python para fazer isso

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
'''
converts sequence of images to video
uses glob pattern and allows skipping images

---
uses [sk-video](https://github.com/scikit-video/scikit-video)
'''> pip install sk-video'''

backend uses ffmpeg or libav

TODO:
- add more input & output dict opts 

For full list of flags see
- https://ffmpeg.org/ffmpeg.html 
- https://trac.ffmpeg.org/wiki/Encode/H.264

Note: Not using opencv2.VideoWriter because it fails silently on Anaconda

'''
from __future__ import print_function
from __future__ import division

import argparse
import glob
import os
from imageio import imread
from skvideo.io import FFmpegWriter
from tqdm import tqdm
from pprint import pprint

parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input_folder', default='.', help='path to folder containing images')
parser.add_argument('-p', '--file_pattern', default='*.png', help='Unix filename pattern. For details see https://docs.python.org/2/library/fnmatch.html')
parser.add_argument('-o', '--output_path', default='output.mp4', help='path to output video file')
parser.add_argument('-n', '--every', default=10, type=int, help='include every nth image. i.e. every==1 uses every image. every==2 takes every other image ')
parser.add_argument('-m', '--max_count', default=None, type=int, help='if > 0, cap at this many frames')
parser.add_argument('-v', '--verbose', default=False, type=int, help='dump a lot of stuff to the console')

# ffmpeg args
parser.add_argument('-r', '--fps', default='30', type=str, help='frames per second')
parser.add_argument('-vcodec', default='libx264', type=str, help='output video codec')
parser.add_argument('-b', '--bitrate', default=None, type=str, help='bitrate')
parser.add_argument('-crf', default=None, type=str, help='Constant Rate Factor. The range of the CRF scale is 0–51, where 0 is lossless, 23 is the default, and 51 is worst quality possible. A lower value generally leads to higher quality, and a subjectively sane range is 17–28. Consider 17 or 18 to be visually lossless or nearly so; it should look the same or nearly the same as the input but it isnt technically lossless')
args = parser.parse_args()


#%% Get input file list
glob_path = os.path.join(os.path.expanduser(os.path.expandvars(args.input_folder)), args.file_pattern)

# read all files in folder matching pattern
print('Reading folder "{}"'.format(glob_path))
paths = sorted(glob.glob(glob_path))
args.stats = {'file_count_total' : len(paths) }
print(args.stats['file_count_total'], 'files found')

# skip 
if args.every > 1:
    paths = [x for i,x in enumerate(paths) if i % args.every == 0]
    args.stats['file_count_with_skip'] = len(paths)
    print(args.stats['file_count_with_skip'], 'files with skip')

# cap to max_count
if args.max_count:
    paths = paths[:args.max_count]
    args.stats['file_count_capped'] = len(paths)
    print(args.stats['file_count_capped'], 'files after cap')

#%% init video writer with parameters
inputdict = {}
outputdict = {}

if args.fps:
    inputdict['-r'] = args.fps
    outputdict['-r'] = args.fps           

if args.vcodec: outputdict['-vcodec'] = args.vcodec
if args.bitrate: outputdict['-b'] = args.bitrate
if args.crf: outputdict['-crf'] = args.crf

video_writer = FFmpegWriter(args.output_path, inputdict=inputdict, outputdict=outputdict)

#%%
print('Starting with args:')
pprint(vars(args))
for path in tqdm(paths):
    img = imread(path)
    if args.verbose: print('processing file', i, path)
    video_writer.writeFrame(img)

print('\n-')
print('Finished. Video saved at', args.output_path)

video_writer.close()
    
por memo 03.03.2018 / 15:12