web-dev-qa-db-ja.com

FFMPEGを使用して、iPhone / iPodおよびFlashプレーヤーで動画を確実にMP4に変換する

Flashプレーヤーとiphone/iPod touchの両方で使用できるようにビデオを変換する必要があります。私はffmpegで次のバッチスクリプトを使用しています。

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

これは常にmp4ファイルを出力し、PCでいつでも再生できます。ビデオは私のiphone 3GSでも問題なく再生されるようです。ただし、一部の入力ファイルでは、古いバージョンのiPhone(3GおよびiPod touch)では機能しません。

そのようなファイルからのffmpeg出力は次のとおりです。

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

私の疑いは、それがオーディオエンコーディングと関係があるということです。もしそうなら、誰かがそれを強制的にオーディオを適切なフォーマットに再エンコードする方法を知っていますか?

他のアイデアはありますか?

17
Jake Stevenson

警告:この回答は10年前のものであり、動作しないことが報告されています。


問題は、H.264レベルがレベル4.2であることだと思います。

Appleデバイスの一部は3.0までしかサポートしていません。

これが私が通常使用するFFMPEG設定です。

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

必要に応じて、レート、サイズ、ビットレートを調整できます。重要な設定は、ベースライン構成パラメーターにあります。

3
cdeutsch

ffmpeg wiki は、特定のデバイス用にH.264をエンコードする方法に関するいくつかの有用な最新のガイダンスを提供します。ここに抜粋があります:

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

リストされたffmpeg設定が機能しません(「ベースライン」プリセットがリストされていないようです)、ベースラインを参照しないffmpeg設定、ここに投稿しました iPhone "cannot play")。 mp4 H.264ビデオファイル

ネタバレ:

 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 

公式のAppleリファレンス: http://developer.Apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html

2
jeffreypriebe

this python script を試してください。

自分で書きました。多分あなたもそれが役に立つでしょう。ファイルをmp4に変換します。

SOルールのため、ここでは完全なソースコードを使用します。

#!/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 test.mov -profile:v baseline -level 3.0  test.mp4

これにより一部の機能が無効になりますが、互換性が向上します。

また、品質とファイルサイズを操作するために追加するいくつかの便利なオプションタグを次に示します。

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

-crf: 0-51

(プリセットは、ビデオを圧縮するのにかかる時間を変更します。ファイルサイズが大きくなると速くなり、ファイルサイズが小さくなると遅くなります。一方、crfはビデオ品質を変更します。高品質の場合はファイルサイズが大きくなり、低品質の場合は小さくなります。ファイルサイズ。)

1
jamiestroud69
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