2010-05-21 56 views
17

Tôi cần chuyển đổi video để sử dụng trong cả trình phát flash và cảm ứng iphone/ipod. Tôi đang sử dụng tập lệnh theo lô sau với ffmpeg:Sử dụng FFMPEG để chuyển đổi video thành mp4 cho iphone/ipod và flash player

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

Điều này luôn xuất ra tệp mp4 và tôi luôn có thể phát trên máy tính của mình. Các video cũng có vẻ chơi tốt trên iPhone 3GS của tôi. Nhưng với một số tập tin đầu vào nó sẽ không hoạt động đối với các phiên bản cũ hơn của iPhone (3G và iPod touch).

Dưới đây là đầu ra ffmpeg từ một tập tin ví dụ:

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 

nghi ngờ của tôi là nó có cái gì để làm với mã hóa âm thanh. Nếu vậy, không ai biết làm thế nào để buộc nó để reencode âm thanh sang định dạng thích hợp?

Bất kỳ ý tưởng nào khác?

Trả lời

3

Tôi nghĩ vấn đề là mức H.264 là cấp 4.2.

Một số thiết bị của Apple chỉ hỗ trợ tối đa 3.0.

Dưới đây là các thiết lập FFMPEG Tôi thường sử dụng:

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 

Bạn có thể điều chỉnh tỷ lệ, kích thước và bitrate khi cần thiết. Các thiết lập quan trọng là trong param cấu hình đường cơ sở.

+0

Khi tôi cố gắng này, FFMPEG nói với tôi "[libx264 @ 0x7f85e8845400] cấu hình cao, mức 1.3" Làm thế nào tôi có thể sửa lỗi này? – mxg

+9

tệp cấu hình cơ bản ở đâu/ở đâu? – badbod99

+0

đây có thể là các cấu hình cơ bản được đề cập đến trong câu trả lời https://github.com/FFmpeg/FFmpeg/tree/master/presets – mulllhausen

2

Các thiết lập ffmpeg niêm yết đã không làm việc cho tôi (tôi dường như không có "cơ sở" cài sẵn niêm yết), cài đặt ffmpeg mà không tham khảo cơ bản, tôi đã đăng ở đây: 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 

Apple tham khảo chính thức về đề tài này: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html

2

Hãy thử this python script.

Tôi đã tự viết nó. Có lẽ bạn cũng sẽ thấy nó hữu ích. Nó chuyển đổi tập tin sang mp4.

Do SO quy tắc ở đây toàn bộ mã nguồn:

#!/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

Các ffmpeg wiki cung cấp một số hữu ích cập nhật hướng dẫn về cách để mã hóa H.264 cho các thiết bị cụ thể. Dưới đây là một đoạn trích:

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

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên đưa các phần quan trọng của câu trả lời vào đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. – brezanac

+0

Tôi vừa thêm bảng. Thật khó hiểu vì một số câu trả lời ở trên đã lỗi thời nhưng tôi đồng ý rằng có ích trong câu trả lời. Bằng cách này, có liên kết wiki và bản sao nội tuyến chỉ trong trường hợp. – Pierz

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

này vô hiệu hóa một số tính năng nhưng cung cấp khả năng tương thích tốt hơn.

Ngoài ra, đây là một số thẻ tùy chọn hữu ích để thêm để làm việc với chất lượng và kích cỡ file:

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

-crf: 0-51 

(Sửa cài sẵn phải mất bao lâu để nén video của bạn, với nhận nhanh hơn một kích thước tập tin lớn hơn, và chậm hơn nhận được kích thước tệp nhỏ hơn, trong khi crf sửa đổi chất lượng video, với chất lượng cao hơn có kích thước tệp lớn hơn và chất lượng thấp hơn có kích thước tệp nhỏ hơn.)

Các vấn đề liên quan