web-dev-qa-db-fra.com

Utilisation de FFMPEG pour convertir de manière fiable des vidéos en MP4 pour iPhone / iPod et Flash Lecteurs

J'ai besoin de convertir des vidéos pour une utilisation dans un lecteur Flash et l'iPhone/iPod Touch. J'utilise le script de lot suivant avec FFMPEG:

@echo off
ffmpeg.exe -i %1 -s qvga -acodec libfaac -ar 22050 -ab 128k -vcodec libx264 -threads 0 -f iPod %2

Cela génère toujours un fichier MP4 et je peux toujours le lire sur mon PC. Les vidéos semblent aussi jouer de mon iPhone 3GS. Mais avec certains fichiers d'entrée, cela ne fonctionnera pas pour les versions iPhone plus anciennes (3G et iPod Touch).

Voici la sortie FFMPEG d'un de ces fichiers:

D:\ffmpeg>encode.bat d:\temp\recording.flv d:\temp\out.m4v
FFmpeg version SVN-r18709, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --enable-memalign-hack --prefix=/mingw --cross-prefix=i686-ming
w32- --cc=ccache-i686-mingw32-gcc --target-os=mingw32 --Arch=i686 --cpu=i686 --e
nable-avisynth --enable-gpl --enable-zlib --enable-bzlib --enable-libgsm --enabl
e-libfaac --enable-libfaad --enable-pthreads --enable-libvorbis --enable-libtheo
ra --enable-libspeex --enable-libmp3lame --enable-libopenjpeg --enable-libxvid -
-enable-libschroedinger --enable-libx264
  libavutil     50. 3. 0 / 50. 3. 0
  libavcodec    52.27. 0 / 52.27. 0
  libavformat   52.32. 0 / 52.32. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libswscale     0. 7. 1 /  0. 7. 1
  built on Apr 28 2009 04:04:42, gcc: 4.2.4
[flv @ 0x187d650]skipping flv packet: type 18, size 164, flags 0
Input #0, flv, from 'd:\temp\recording.flv':
  Duration: 00:00:07.17, start: 0.001000, bitrate: N/A
    Stream #0.0: Video: flv, yuv420p, 320x240, 1k tbr, 1k tbn, 1k tbc
    Stream #0.1: Audio: nellymoser, 44100 Hz, mono, s16
[libx264 @ 0x13518b0]using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE
4.2
[libx264 @ 0x13518b0]profile Baseline, level 4.2
Output #0, iPod, to 'd:\temp\out.m4v':
    Stream #0.0: Video: libx264, yuv420p, 320x240, q=2-31, 200 kb/s, 1k tbn, 1k
tbc
    Stream #0.1: Audio: libfaac, 22050 Hz, mono, s16, 128 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame=   90 fps=  0 q=-1.0 Lsize=     128kB time=6.87 bitrate= 152.4kbits/s
video:92kB audio:32kB global headers:1kB muxing overhead 2.620892%
[libx264 @ 0x13518b0]slice I:8     Avg QP:29.62  size:  7047
[libx264 @ 0x13518b0]slice P:82    Avg QP:30.83  size:   467
[libx264 @ 0x13518b0]mb I  I16..4: 17.9%  0.0% 82.1%
[libx264 @ 0x13518b0]mb P  I16..4:  0.6%  0.0%  0.0%  P16..4: 23.1%  0.0%  0.0%
 0.0%  0.0%    skip:76.3%
[libx264 @ 0x13518b0]final ratefactor: 57.50
[libx264 @ 0x13518b0]SSIM Mean Y:0.9544735
[libx264 @ 0x13518b0]kb/s:8412.6

Ma suspicion est que cela a quelque chose à voir avec le codage audio. Si oui, quelqu'un sait-il comment le forcer à réenregorter le son au format approprié?

Toute autre idée?

17
Jake Stevenson

AVERTISSEMENT: Cette réponse a 10 ans et a signalé de ne plus travailler.


Je pense que la question est le niveau H.264 étant le niveau 4.2.

Certains des Apple disposent uniquement de prises en charge jusqu'à 3.0.

Voici les paramètres FFMPEG que j'utilise habituellement:

ffmpeg -i YOUR-INPUT.wmv -s qvga -b 384k -vcodec libx264 -r 23.976 -acodec libfaac -ac 2 -ar 44100 -ab 64k -vpre baseline -crf 22 -deinterlace -o YOUR-OUTPUT.MP4

Vous pouvez ajuster le taux, la taille et le débit au besoin. Les paramètres importants sont dans le paramètre de configuration de base.

3
cdeutsch

Le FFMPEG WIKI fournit des directives utiles à jour sur la manière d'encoder H.264 pour des périphériques particuliers. Voici un extrait:

iOS Compatability ([​source][2])
Profile  Level Devices                                                     Options
Baseline 3.0  All devices                                                  -profile:v baseline -level 3.0
Baseline 3.1  iPhone 3G and later, iPod touch 2nd generation and later     -profile:v baseline -level 3.1
Main     3.1  iPad (all vers), Apple TV 2 and later, iPhone 4 and later    -profile:v main -level 3.1
Main     4.0  Apple TV 3 and later, iPad 2 and later, iPhone 4s and later  -profile:v main -level 4.0
High     4.0  Apple TV 3 and later, iPad 2 and later, iPhone 4s and later  -profile:v high -level 4.0
High     4.1  iPad 2 and later, iPhone 4s and later, iPhone 5c and later   -profile:v high -level 4.1
High     4.2  iPad Air and later, iPhone 5s and later                      -profile:v high -level 4.2
2
Pierz

Les paramètres FFMPEG cotés ne fonctionnaient pas pour moi (je ne semble pas avoir la liste de base "Baseline" répertorié), les paramètres FFMPEG qui ne font pas référence à la base de référence, j'ai posté ici: iPhone "Impossible de jouer". Fichier vidéo MP4 H.264

Divulgacher:

[.____ -acodec libfaac -ac 2 -ar 48000 -Ab 192kut.mp4 [.____]

L'officiel Apple Référence sur le sujet: - http://developer.apple.com/library/safari/#documentation/aplpleeapplications/reference/safariwebcontent/CreateVideOforsafarionIphone/creatiingVideOforsafarionIPhone.html

2
jeffreypriebe

Essayez ce python Script .

Je l'ai écrit pour moi-même. Peut-être que vous le trouverez utile aussi. Il convertit des fichiers en MP4.

À cause de SO règles ici le code source complet:

#!/usr/bin/python

# Copyright (C) 2007-2010 CDuke
# This program is free software. You may distribute it under the terms of
# the GNU General Public License as published by the Free Software
# Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but

# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# This program converts video files to mp4, suitable to be played on an iPod
# or an iPhone. It is careful about maintaining the proper aspect ratio.

from __future__ import division
from datetime import datetime
import sys
import argparse
import os
import re
import shlex
import time
from subprocess import Popen, PIPE

DEFAULT_ARGS = '-f mp4 -y -vcodec libxvid -maxrate 1000k -mbd 2 -qmin 3 -qmax 5 -g 300 -bf 0 -acodec libfaac -ac 2 -flags +mv4 -trellis 2 -cmp 2 -subcmp 2'
#DEFAULT_ARGS = '-f mp4 -y -vcodec mpeg4 -vtag xvid -maxrate 1000k -mbd 2 -qmin 3 -qmax 5 -g 300 -bf 0 -acodec libfaac -ac 2 -r 30000/1001 -flags +mv4 -trellis 2 -cmp 2 -subcmp 2'
#DEFAULT_ARGS = '-y -f mp4 -vcodec libxvid -acodec libfaac'
DEFAULT_BUFSIZE = '4096k'
DEFAULT_AUDIO_BITRATE = '128k'
DEFAULT_VIDEO_BITRATE = '400k'
FFMPEG = '/usr/bin/ffmpeg'

class device:
    '''Describe properties of device'''
    def __init__(self, name, width, height):
        self.name = name
        self.width = width
        self.height = height

class videoFileInfo:
    def __init__(self, width, height, duration):
        self.width = width
        self.height = height
        self.duration = duration

devices = [device('iPod', 320, 240), device('iphone', 480, 320),
device('desire', 800, 480)]

def getOutputFileName(inputFileName, outDir):
    if outDir == None:
        outFileName = os.path.splitext(inputFileName)[0] + '.mp4'
    else:
        outFileName = os.path.join(outDir, os.path.basename(inputFileName))
    return outFileName

def getVideoFileInfo(fileName):
    p = Popen([FFMPEG, '-i', fileName], stdout = PIPE, stderr = PIPE)
    fileInfo = p.communicate()[1]
    videoRes = re.search(b'Video:.+ (\d+)x(\d+)', fileInfo)
    w = float(videoRes.group(1))
    h = float(videoRes.group(2))
    duratMatch = re.search(b'Duration:\s+(\d+):(\d+):(\d+)\.(\d+)', fileInfo)
    duration = float(duratMatch.group(1)) * 3600
    duration += float(duratMatch.group(2)) * 60
    duration += float(duratMatch.group(3))
    duration += float(duratMatch.group(4)) / 10
    fileInfo = videoFileInfo(w, h, duration)
    return fileInfo

def getArguments(width, height, aspect):
    args = {}
    w = width
    h = w // aspect
    h -= (h % 2)
    if h <= height:
        pad = (height - h) // 2
        pad -= (pad % 2)
        pady = pad
        padx = 0
    else:
        # recalculate using the height as the baseline rather than the width
        h = height
        w = int(h * aspect)
        width -= (width % 2)
        pad = (width - w) // 2
        pad -= (pad % 2)
        padx = pad
        pady = 0

    args['width'] = w
    args['height'] = h
    args['padx'] = padx
    args['pady'] = pady
    return args

def getProgressBar(perc):
    convInfo = 'Converted: [{}] {:.2%} \r'
    num_hashes = round(perc * 100 // 2)
    bar = '=' * num_hashes + ' ' * (50 - num_hashes)
    return convInfo.format(bar, perc)

def convert(inputFileName, outputFileName, args, audioBitrate, videoBitrate, devWidth, devHeight, aspect, duration):
    cmd = '{ffmpeg} -i {inFile} {defaultArgs} -bufsize {bufsize} -s {width}x{height} -vf "pad={devWidth}:{devHeight}:{padx}:{pady},aspect={aspect}" -ab {audioBitrate} -b {videoBitrate} {outFile}'.format(ffmpeg=FFMPEG, inFile=inputFileName, defaultArgs=DEFAULT_ARGS, bufsize=DEFAULT_BUFSIZE, devWidth=devWidth, devHeight=devHeight, padx=args['padx'], pady=args['pady'], width=args['width'], height=args['height'], aspect=aspect, audioBitrate=audioBitrate, videoBitrate=videoBitrate, outFile=outputFileName)
#    cmd = '{ffmpeg} -i {inFile} {defaultArgs} -bufsize {bufsize} -s {width}x{height} -ab {audioBitrate} -b {videoBitrate} {outFile}'.format(ffmpeg=FFMPEG, inFile=inputFileName, defaultArgs=DEFAULT_ARGS, bufsize=DEFAULT_BUFSIZE, width=args['width'], height=args['height'], audioBitrate=audioBitrate, videoBitrate=videoBitrate, outFile=outputFileName)
    print(cmd)
    print()
    start = datetime.today()
    print('Converting started at ' + str(start))
    conv = Popen(shlex.split(cmd), Shell=False, stdout=PIPE, stderr=PIPE)
    while conv.poll() is None:
       out = os.read(conv.stderr.fileno(), 2048)
       last = out.splitlines()[-1]
       timeMatch = re.search(b'time=([^\s]+)', last)
       if timeMatch:
           timeDone = float(timeMatch.group(1))
           perc = timeDone / duration
           if sys.version_info > (3, 0):
               exec("print(getProgressBar(perc), end='')")
           else:
               exec("print getProgressBar(perc),")
           sys.stdout.flush()
#       else:
#           print(out)
       time.sleep(0.5)
    print(getProgressBar(1))
    end = datetime.today()
    print('Converting ended at ' + str(end))
    print('Spended time: ' + str(end - start))

class mp4Converter(argparse.Action):
    def __call__(self, parser, namespace, values, option_string = None):
        outdir = namespace.outdir
        for f in values:
            outFileName = getOutputFileName(f.name, outdir)
            fileInfo = getVideoFileInfo(f.name)
            aspect = fileInfo.width / fileInfo.height
            dev = next(d for d in devices if d.name == namespace.device)
            args = getArguments(dev.width, dev.height, aspect)
            convert(f.name, outFileName, args, namespace.AUDIO_BITRATE, namespace.VIDEO_BITRATE, dev.width, dev.height, aspect, fileInfo.duration)
            print('file "{0}" converted successful'.format(f.name))

opts = argparse.ArgumentParser(
    description = 'Converter to MP4',
    epilog = 'made by CDuke 2010')
opts.add_argument('-V','--version',
                  action = 'version',
                  version = '0.0.1')
opts.add_argument('-v', '--verbose',
                  action = 'store_true',
                  default = False,
                  help = 'verbose')
opts.add_argument('-a', '--audio',
                  dest = 'AUDIO_BITRATE',
                  default = DEFAULT_AUDIO_BITRATE,
                  help = 'override default audio bitrate {0}'.format(DEFAULT_AUDIO_BITRATE))
opts.add_argument('-b', '--video',
                  dest = 'VIDEO_BITRATE',
                  default = DEFAULT_VIDEO_BITRATE,
                  help = 'override default video bitrate {0}'.format(DEFAULT_VIDEO_BITRATE))
opts.add_argument('-d', '--device',
                  choices = [d.name for d in devices],
                  default = 'iPod',
                  help = 'device that will play video')
opts.add_argument('-o', '--outdir',
                  help = 'write files to given directory')
opts.add_argument('file',
                  nargs = '+',
                  type = argparse.FileType('r'),
                  action = mp4Converter,
                  help = 'file that will be converted')

opts.parse_args()
2
CDuke
ffmpeg -i input.mov -c:v libx264 -pix_fmt yuv420p -profile:v main -crf 1 -preset medium -c:a aac -movflags +faststart output.mp4
0
Vladislav

enter image description here

ffmpeg.exe -i "Video.mp4" -vcodec libx264 -preset fast -profile:v baseline -lossless 1 -vf "scale=720:540,setsar=1,pad=720:540:0:0" -acodec aac -ac 2 -ar 22050 -ab 48k "Video (SD).mp4"
0
joseferreira_ms