Newest 'ffmpeg' Questions - Stack Overflow

http://stackoverflow.com/questions/tagged/ffmpeg

Les articles publiés sur le site

  • Convert TS with closed captions into MKV/MP4 with sub title

    28 mars 2017, par Sudheesh

    I am trying to convert a TS file ( with US closed captions ) into MKV ( or MP4 ). Currently I am doing using a three step approach.

    Step-1 : Extract the subtitle in srt format.

    ffmpeg -f lavfi -i "movie=test.ts[out0+subcc]" -map s output.srt

    Step-2 : Transcode the TS into MKV

    ffmpeg i test.ts -vcodec libx264 -acodec copy out.mkv

    Step-3 : Add subtitle back to out.mkv

    ffmpeg -i out.mkv -i output.srt -acodec copy -vcodec copy -scodec copy final.mkv.

    I believe all these three steps can be combined in a single ffmeg command. Is there any way to do this?.

  • SEI type 63 truncated ? Best way to convert non-mp4 to web optimized mp4 ?

    28 mars 2017, par Chris Palmer Breuer

    I am trying to convert any video file to a web optimized mp4 format and I tried this sample mkv file to make some tests.

    The following is a message I keep getting for multiple minutes over and over again:

    [NULL @ 0x7f979c00a600] SEI type 63 size 4208 truncated at 88
    [h264 @ 0x7f979b06a000] SEI type 63 size 4208 truncated at 80
    [NULL @ 0x7f979c00a600] SEI type 63 size 4208 truncated at 88
    [h264 @ 0x7f979b002c00] SEI type 63 size 4208 truncated at 80
    [NULL @ 0x7f979c00a600] SEI type 63 size 4208 truncated at 528
    [h264 @ 0x7f979b027400] SEI type 63 size 4208 truncated at 520
    

    The code that I use the convert the mkv file is:

    ffmpeg -i test.mkv -movflags faststart -vcodec h264 -acodec aac -strict -2 test-ffmpeg.mp4
    

    Now, my question is, am I doing anything wrong? Should I just ignore those messages as the file gets created? Is there a more efficient way to create a web optimized mp4 file from a non mp4 file?

    Thanks so much for the help.

  • Traverse folder to convert all contained files

    28 mars 2017, par E.Owen

    I've recently started using ffmpeg with the intention of converting my video library to h265 due to its compression benefits. I would like to run one command and have ffmpeg traverse the folder converting each file, one-by-one into h265. I've checked the documentation Here but I can't get my head around it. Does anybody have a template loop script for me to use?

    I have ffmpeg installed on a Linux box and have successfully converted single files but I have around 400 files to convert, hence the looping question.

    Thanks in advance.

    EDIT: The files I'm waiting to convert are videos with varying containers. I have bee using the python script below, which I have tweaked to suit my needs but isn't working. I will include the error I'm getting and a link to the original below my code.

    import os
    import sys
    import re
    import shutil
    import subprocess
    
    
    __author__ = 'Nikhil'
    
    # Edit options here ##################################################
    outmode = 'mp4'                          #Extension of file
    remover = True                           # Delete original file after conversion complete
    accept_ext = 'mp4 mkv avi divx m4v mpeg mpg wmv'   #Extensions of video files to convert
    
    ffmpeg_exe = "ffmpeg"                    #Path to ffmpeg executable
    ffprobe_exe = "ffprobe"                  #Path to ffprobe executable
    mkvextract_exe = "mkvextract"            #Path to mkvextract executable
    video_codec = 'libx265'                  #Video codec to use
    video_type = 'h265'                      #Name of video codec to check for remux
    audio_codec = 'aac'                      #Audio codec to use
    audio_type = 'aac'                       #Name of audio codec to check for remux
    crf = "28"                               #Video quality for libx264
    vbr = ''                                 #Audio quality
    extract_subtitle = True                  #Extract subtitles?
    subtitle_languages = "en eng english"    #Codes for languages to extract
    threads = 0                              #Number of threads to use in ffmpeg, 0 defaults to all
    additional_ffmpeg = '-preset slow -movflags +faststart'     #Additional flags for ffmpeg, preset sets speed and compression, movflags to make file web optimized
    
    ## END OPTIONS - DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING ##
    
    outformat = 'mp4'
    if outmode == 'mp4':
    outformat = 'mp4'
    elif outmode == 'mkv':
    outformat = 'matroska'
    
    
    def ffmpeg(*args, **kwargs):
    largs = [ffmpeg_exe, ]
    largs.extend(args)
    try:
    return subprocess.check_output(largs, **kwargs).decode('utf-8')
    except:
    return None
    
    def getoutput(cmd):
    if sys.version < '3':
    try:
    return subprocess.check_output(cmd.split(' '))
    except:
    return None
    else:
    return subprocess.getoutput(cmd)
    
    formats = ""
    if getoutput(ffmpeg_exe + ' -formats'):
    formats = getoutput(ffmpeg_exe + ' -formats 2')
    else:
    exit(1)
    
    if ('E mp4' in formats) and ('E matroska' in formats):
    print("You have the suitable formats")
    else:
    print("You do not have both the mkv and mp4 formats...Exiting!")
    exit(1)
    
    codecs = getoutput(ffmpeg_exe + ' -codecs 2')
    
    if video_codec in codecs:
    print("Check " + video_codec + " Audio Encoder ... OK")
    else:
    print("Check " + video_codec + " Audio Encoder ... NOK")
    exit(1)
    
    if audio_codec in codecs:
    print("Check " + audio_codec + " Audio Encoder ... OK")
    else:
    print("Check " + audio_codec + " Audio Encoder ... NOK")
    exit(1)
    
    print("Your FFMpeg is OK\nEntering File Processing\n")
    
    subtitle_languages = subtitle_languages.lower()
    
    def process_file(path, file):
    extension = os.path.splitext(file)[1].replace(".", "")
    filename = os.path.splitext(file)[0]
    
    if extension in accept_ext:
    print(file + " is an acceptable extension. Checking file...")
    else:
    print(file + " is not an acceptable extension. Skipping...")
    return
    
    if ffprobe_exe:
    file_info = getoutput('"' + ffprobe_exe + '"' + " " + '"' + os.path.join(path, file) + '"')
    else:
    file_info = ffmpeg("-i", os.path.join(path, file))
    
    if 'Invalid data found' in file_info:
    print("File " + file + " is NOT A VIDEO FILE cannot be converted!")
    return
    
    encode_crf = []
    if file_info.find("Video: " + video_type) != -1:
    vcodec = 'copy'
    print("Video is " + video_type + ", remuxing....")
    else:
    vcodec = video_codec
    if crf:
    encode_crf = ["-crf", "" + crf]
    print("Video is not " + video_type + ", converting...")
    
    encode_vbr = []
    if "Audio: " + audio_type in file_info:
    acodec = 'copy'
    print("Audio is " + audio_type + ", remuxing....")
    else:
    acodec = audio_codec
    if vbr:
    encode_vbr = ["-vbr", "" + vbr]
    print("Audio is not " + audio_type + ", converting...")
    
    if extension == outmode and vcodec == 'copy' and acodec == 'copy':
    print(file + " is already " + outmode + " and no conversion needed. Skipping...")
    return
    
    print(
    "Using video codec: " + vcodec + " audio codec: " + acodec + " and Container format " + outformat + " for\nFile: " + file + "\nStarting Conversion...\n")
    
    filename = filename.replace("XVID", video_type)
    filename = filename.replace("xvid", video_type)
    
    try:
    args = ['-i', os.path.join(path, file), '-y', '-f', outformat, '-acodec', acodec]
    if encode_vbr:
    args.extend(encode_vbr)
    args.extend(['-vcodec', vcodec])
    if encode_crf:
    args.extend(encode_crf)
    if additional_ffmpeg:
    args.extend(additional_ffmpeg.split(" "))
    if threads:
    args.extend(['-threads', str(threads)])
    args.append(os.path.join(path, filename + '.temp'))
    ffmpeg(*args)
    print("")
    except Exception as e:
    print("Error: %s" % e)
    print("Removing temp file and skipping file")
    if os.path.isfile(os.path.join(path, filename + '.temp')):
    os.remove(os.path.join(path, filename + '.temp'))
    return
    
    if extract_subtitle and (file_info.find("Subtitle:") != -1):
    print("Extracting Subtitles")
    matches = re.finditer("Stream #(\d+):(\d+)\((\w+)\): Subtitle: (.*)", file_info)
    for m in matches:
    if m.group(3).lower() not in subtitle_languages.split(" "):
    continue
    try:
    if 'subrip' in m.group(4):
    sub_format = 'copy'
    sub_ext = '.srt'
    elif mkvextract_exe and 'hdmv_pgs' in m.group(4):
    subprocess.check_output([mkvextract_exe, 'tracks', os.path.join(path, file),
    m.group(2) + ':' + os.path.join(path, filename + '.' + m.group(
    3) + '.' + m.group(2) + '.sup')])
    continue
    else:
    sub_format = 'srt'
    sub_ext = '.srt'
    ffmpeg("-i", os.path.join(path, file), '-y', '-map', m.group(1) + ':' + m.group(2), '-c:s:0',
    sub_format,
    os.path.join(path, filename + '.' + m.group(3) + '.' + m.group(2) + sub_ext))
    print("")
    except Exception as e:
    print("Error: %s" % e)
    print("Deleting subtitle.")
    if os.path.isfile(os.path.join(path, filename + '.' + m.group(3) + '.' + m.group(2) + sub_ext)):
    os.remove(os.path.join(path, filename + '.' + m.group(3) + '.' + m.group(2) + sub_ext))
    
    if remover:
    print("Deleting original file: " + file)
    os.remove(os.path.join(path, file))
    
    if outmode == extension:
    shutil.move(os.path.join(path, filename + ".temp"), os.path.join(path, filename + ".enc." + outmode))
    filename += ".enc"
    else:
    shutil.move(os.path.join(path, filename + ".temp"), os.path.join(path, filename + "." + outmode))
    
    
    def process_directory(path):
    if os.path.isfile(os.path.join(path, ".noconvert")):
    return
    for file in os.listdir(path):
    filepath = os.path.join(path, file)
    if os.path.isdir(filepath):
    process_directory(filepath)
    elif os.path.isfile(filepath):
    process_file(path, file)
    
    
    for arg in sys.argv[1:]:
    if os.path.isdir(arg):
    process_directory(arg)
    elif os.path.isfile(arg):
    process_file(os.path.dirname(arg), os.path.basename(arg))
    

    The error I am getting is this:

    Traceback (most recent call last):
    File "/media/569f/ethan1878/bin/convert.py", line 209, in 
    process_file(os.path.dirname(arg), os.path.basename(arg))
    File "/media/569f/ethan1878/bin/convert.py", line 100, in process_file
    if 'Invalid data found' in file_info:
    TypeError: argument of type 'NoneType' is not iterable
    

    and the original file is hosted Here (as a .txt file)

  • Validation failed : Video Paperclip::Errors::NotIdentifiedByImageMagickError

    28 mars 2017, par ACIDSTEALTH

    I have a model with an attached video. I want to create a scaled version of the video along with a series of thumbnails. I have the following setup:

    has_attached_file :video,
        styles: {
            original: { format: 'mp4', processors: [:transcoder] },
            large: { geometry: "720x720", format: 'jpg', processors: [:thumbnail] },
            medium: { geometry: "540x540", format: 'jpg', processors: [:thumbnail] },
            thumb: { geometry: "180x180", format: 'jpg', processors: [:thumbnail] }
        },
        default_url: ""
    

    When I test this in my development environment it works perfectly. The video and all images are correctly sized. When I deploy to Heroku however, I get the following error:

    Validation failed: Video Paperclip::Errors::NotIdentifiedByImageMagickError
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/validations.rb:78:in `raise_validation_error'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/validations.rb:50:in `save!'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/attribute_methods/dirty.rb:30:in `save!'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/transactions.rb:324:in `block in save!'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/transactions.rb:395:in `block in with_transaction_returning_status'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `block in transaction'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/transaction.rb:189:in `within_new_transaction'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `transaction'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/transactions.rb:211:in `transaction'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/transactions.rb:392:in `with_transaction_returning_status'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/transactions.rb:324:in `save!'
    /app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.2/lib/active_record/suppressor.rb:45:in `save!'
    /app/app/models/concerns/snapshot_methods.rb:37:in `copy_from_ziggeo!'
    /app/app/workers/snapshot_transcoder.rb:16:in `perform'
    /app/vendor/bundle/ruby/2.3.0/gems/resque-status-0.5.0/lib/resque/plugins/status.rb:161:in `safe_perform!'
    /app/vendor/bundle/ruby/2.3.0/gems/resque-status-0.5.0/lib/resque/plugins/status.rb:137:in `perform'
    

    What am I missing here? I've searched for NotIdentifiedByImageMagickError and scanned numerous other questions on this issue, but have not had any success fixing my problem.

    Most of the solutions I've seen involve setting Paperclip.options[:command_path] = "/usr/bin/identify" in development. Since my problem is only on production, I tried applying this to production, subbing in the correct path for my production environment, like so:

    Paperclip.options[:command_path] = "/app/vender/imagemagick/bin/identify"
    

    This had no effect. Neither did /app/vender/imagemagick/bin.

  • ffmpeg : Select frames at % position of video

    28 mars 2017, par Matt Joiner

    I'm trying to create a 2x2 tile thumbnail of a video, that contains frames from 20%, 40%, 60%, and 80% through a video. I see that I need to use a video filter, with select, but can't work out what options will do this. I want to do something like this:

    ffmpeg -i video.avi -frames 1 -vf "select=not(mod(pos\,0.2)),tile=2x2" tile.png
    

    Where position would be the position in the video from 0.0 to 1.0. How do I do this, or what are my options?