Skip to content

Instantly share code, notes, and snippets.

@mahmoud
Created February 1, 2015 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mahmoud/2fa52e7e333b0ee83436 to your computer and use it in GitHub Desktop.
Save mahmoud/2fa52e7e333b0ee83436 to your computer and use it in GitHub Desktop.
a codification of a particular method of using ffmpeg to clean up certain FLVs.
# cropping mp4 video in ffmpeg.
#
# this does require a re-encode but the following process created video
# half the size with no perceptible change in quality. audio is unaffected.
# detect area to crop
ffplay -i show.mp4 -vf "cropdetect=24:16:0"
# crop to 944x720, x-offset=170, y-offset=0 (removing vertical black bars)
ffmpeg -i show.mp4 -vf "crop=944:720:170:0" show_cropped.mp4
# do that in a loop for five shows
for i in $(seq 1 5); do ffmpeg -i show_10${i}.mp4 -vf "crop=944:720:170:0" show_10${i}_cropped.mp4; done
# NOTE: "-strict -2" may be necessary depending on your ffmpeg's codec support.
"""
Translates MP4-encoded FLVs to native MP4 and then concatenates
them. It is up to the encoder to ensure that the original FLVs
actually contain MP4. Expects ffmpeg to be installed. No python
requirements.
Usage:
python flv2mp4.py --output ../show.mp4 *.flv
Relevant commands for easy reference:
# switches from an FLV container to a native MP4 container without reencoding
ffmpeg -i show_1.flv -codec show_1.mp4
# concatenates the mp4s listed in file_list.txt without reencoding.
ffmpeg -f concat -i file_list.txt -c copy show_joined.mp4
"""
import os
import shutil
import argparse
import subprocess
def parse_args():
prs = argparse.ArgumentParser()
prs.add_argument('input_files', nargs='+')
prs.add_argument('--output')
prs.add_argument('--overwrite', action='store_true')
return prs.parse_args()
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(path):
return
raise
return
def convert_flv(flv_path, dest_path, overwrite=False):
if os.path.isdir(dest_path):
dest_fn = os.path.splitext(os.path.split(flv_path)[1])[0] + '.mp4'
dest_path = os.path.join(dest_path, dest_fn)
print ' - writing to destination path:', dest_path
command = ['ffmpeg']
if overwrite:
command.append('-y')
else:
command.append('-n')
command.extend(['-i', flv_path, '-codec', 'copy', dest_path])
print command
output = subprocess.check_output(command)
return dest_path
def concat_mp4s(mp4_list, output_path, scratch_path, overwrite=False):
file_list_path = make_file_list(mp4_list, scratch_path)
command = ['ffmpeg', '-f', 'concat', '-i', file_list_path, '-c', 'copy']
if overwrite:
command.append('-y')
else:
command.append('-n')
command.append(output_path)
print command
output = subprocess.check_output(command)
print output
return output
def make_file_list(mp4_list, scratch_path):
lines = []
for mp4_path in mp4_list:
lines.append("file '%s'" % mp4_path.replace("'", r"\'"))
file_list_path = os.path.join(scratch_path, 'file_list.txt')
with open(file_list_path, 'w') as f:
f.write('\n'.join(lines))
return file_list_path
def make_output_fn(input_fns):
output_fn = os.path.splitext(input_fns[0])[0] + '.mp4'
if len(input_fns) > 1:
output_fn = os.path.commonprefix(input_fns).strip() + '_joined.mp4'
return output_fn
def main():
args = parse_args()
input_fns = args.input_files
output_fn = args.output
overwrite = args.overwrite
cur_path = os.path.abspath('.')
if not output_fn:
output_dir = cur_path
output_fn = make_output_fn(input_fns)
elif os.path.isdir(output_fn):
output_dir = output_fn
output_fn = make_output_fn(input_fns)
else:
output_dir, output_fn = os.path.split(output_fn)
output_dir = output_dir or cur_path
output_path = os.path.abspath(os.path.join(output_dir, output_fn))
scratch_dir = os.path.join(output_dir, 'tmpflvconv')
mkdir_p(scratch_dir) # TODO: mkdtemp?
try:
mp4_list = []
for fn in input_fns:
mp4_path = convert_flv(fn, scratch_dir, overwrite=overwrite)
mp4_list.append(mp4_path)
concat_mp4s(mp4_list, output_path, scratch_dir, overwrite=overwrite)
print 'output mp4 successfully written to', output_path
finally:
shutil.rmtree(scratch_dir)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment