2010-05-21 9 views
17

Ich muss Videos für den Einsatz in einem Flash-Player und dem iPhone/iPod Touch zu konvertieren. Ich verwende die folgende Batch-Skript mit ffmpeg:Mit FFMPEG Videos zuverlässig in mp4 für iPhone/iPod und Flash-Player konvertieren

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

Diese immer eine mp4-Datei gibt, und ich kann es immer auf meinem PC spielen. Die Videos scheinen auch gut auf meinem iPhone 3GS zu spielen. Aber mit einigen Eingabedateien funktioniert es nicht für ältere iphone Versionen (3G und iPod touch).

Hier ist der ffmpeg Ausgabe von einer solchen Datei:

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 

Mein Verdacht ist, dass es etwas mit der Audio-Codierung zu tun hat. Wenn ja, weiß jemand, wie man es zwingt, das Audio zum korrekten Format neu zu kodieren?

Irgendwelche anderen Ideen?

Antwort

3

Ich denke, das Problem ist die H.264-Ebene ist Level 4.2.

Einige Apple-Geräte unterstützen nur bis zu 3,0.

Hier ist die FFMPEG Einstellungen, die ich in der Regel verwenden:

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 

Sie können die Geschwindigkeit, Größe und Bitrate nach Bedarf anpassen. Die wichtigen Einstellungen sind im Baseline-Konfigurationsparameter.

+0

Wenn ich dies versuchen, sagt FFMPEG mich "[libx264 @ 0x7f85e8845400] High Profile, Level 1.3" Wie kann ich dieses Problem beheben? – mxg

+9

Was/Wo ist die Baseline-Konfigurationsdatei? – badbod99

+0

Dies sind wahrscheinlich die Basiskonfigurationen, auf die in der Antwort verwiesen wird https://github.com/FFmpeg/FFmpeg/tree/master/presets – mulllhausen

2

Die aufgeführten ffmpeg Einstellungen nicht für mich arbeiten (ich scheine nicht die „Baseline“ Preset zu haben aufgelistet), ffmpeg Einstellungen, die Baseline-Referenz nicht, habe ich geschrieben hier über: iPhone "cannot play" .mp4 H.264 video file

Spoiler :

 
ffmpeg -i INPUT -s 320x240 -r 30000/1001 -b 200k -bt 240k -vcodec libx264 -coder 0 -bf 0 -refs 1 -flags2 -wpred-dct8x8 -level 30 -maxrate 10M -bufsize 10M -acodec libfaac -ac 2 -ar 48000 -ab 192k OUTPUT.mp4 

die auf dem Thema offizielle Apple-Referenz: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html

2

Versuchen this python script.

Ich schrieb es für mich. Vielleicht finden Sie es auch nützlich. Es konvertiert Dateien in MP4.

Wegen SO Regeln hier den vollständigen Quellcode:

#!/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() 
1

Die ffmpeg wiki bietet einige nützliche auf dem neuesten Stand Anleitung, wie H.264 für bestimmte Geräte zu kodieren. Hier ein Auszug:

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 
+0

Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier einzubeziehen und den Link als Referenz zur Verfügung zu stellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. – brezanac

+0

Ich habe gerade die Tabelle hinzugefügt. Es ist schwierig, da einige der obigen Antworten veraltet sind, aber ich stimme zu, dass es nützlich ist, die Informationen in der Antwort zu haben. Auf diese Weise gibt es den Wiki-Link und eine Inline-Kopie für alle Fälle. – Pierz

0
ffmpeg -i test.mov -profile:v baseline -level 3.0 test.mp4 

Dies deaktiviert einige Funktionen, bietet aber eine bessere Kompatibilität.

Auch hier sind einige nützliche optionale Tags für die Arbeit mit der Qualität und Dateigröße hinzuzufügen:

-preset: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo 

-crf: 0-51 

(Voreinstellung ändert, wie lange es dauert, um Ihr Video zu komprimieren, mit schneller eine größere Dateigröße bekommen, und langsamer erhalten eine kleinere Dateigröße, während Crf die Videoqualität verändert, mit höherer Qualität eine größere Dateigröße und niedrigere Qualität mit einer kleineren Dateigröße.)

Verwandte Themen