Koda om filmer för Android och iPhone

Obs: ffmpeg är ett rörligt mål, och sedan den här guiden skrevs har anvisningarna i den slutat fungera. Men har du en version av ffmpeg från början av 2011 kan du ju alltid försöka ändå… ,)

* * *

Problem: Du har en film, kanske är den nedtankad från SVTPlay eller på en DVD-skiva, och nu vill du se på den i mobilen. Men den är för otymplig!

Lösning: Koda om filmen till telefonbrukbart mp4-format.

Svårighetsgrad: Lätt omständigt. (Svårare dock för Windows-användare, som saknar $-skal.)

Du behöver:

Om du ska rippa filmen från en DVD behöver du även något program för detta. Om du däremot redan har en färdig filmfil, till exempel en sådan du dragit hem från SVTPlay, så kan du klicka här för att hoppa till nästa avsnitt.

Rippa från DVD (med MEncoder)

För att kopiera från det .vob-format som film-DVD:er använder, så behöver du även något program som kan kopiera filmen till en typisk container i stil med .mpg eller .avi. MEncoder håller måttet, och följer med MPlayer. Så vitt jag vet kan du även göra detta med VLC i Windows, men hur får du allt lista ut själv.

För att med MEncoder skapa filmfilen du behöver från en DVD, ska du först ta reda på vilket kapitel du vill ha.

Prova dig fram med följande kommandon:

$ mplayer dvd://1

$ mplayer dvd://2

$ mplayer dvd://3

Använd parametern -dvd-device om MPlayer inte hittar din DVD-skiva:

## Du kan läsa direkt från enheten:
$ mplayer -dvd-device /dev/cd0c dvd://1

## Om du mountar skivan kan du läsa från den så här istället:
$ mplayer -dvd-device /mnt/disc dvd://1

## Eller förstås så här, om du rippat den rakt av:
$ mplayer -dvd-device metropolis.iso dvd://1

När du funnit rätt kapitel är det dags att kopiera filmen. Glöm inte att använda samma -dvd-device-parameter, eller förstås att ange rätt kapitel:

## Utan -dvd-device:
$ mencoder -oac copy -ovc copy -o "film".mpg dvd://3

## Med -dvd-device:
$ mencoder -oac copy -ovc copy -o "film".mpg -dvd-device metropolis.iso dvd://3

Nu har du skaffat dig filen film.mpg. Dags att konvertera!

Så här gör du

När jag konverterar filmer för mobiltelefon, så är jag ute efter förutsägbar filstorlek. Guiden utgår därför från att vad du önskar dig är 100 megabyte per timme film. I mitt tycke räcker detta alldeles utmärkt. Parametrar för andra MB/h finns sist i inlägget.

  1. Du behöver artbestämma videon litet grand. Det handlar om saker som är unika för varje film. Med MPlayer kan det göras så här:

    $ mplayer -frames 0 -identify "film".mp4 | egrep "(VIDEO_WIDTH|VIDEO_HEIGHT|VIDEO_FPS|AUDIO_BITRATE|AUDIO_FORMAT)"

    Observera att kommandot som ska köras inte får radbrytas, trots att det kanske ser radbrutet ut här bloggen. Utmatningen ser ut ungefär så här:

    ID_VIDEO_WIDTH=640
    ID_VIDEO_HEIGHT=360
    ID_VIDEO_FPS=25.000
    ID_AUDIO_FORMAT=MP4A
    ID_AUDIO_BITRATE=0
    ID_AUDIO_BITRATE=128000

    • Filmens aspect ratio är 16:9, eftersom 640 genom 360 är 1,777…. Ofta skrivs det 1.77:1 istället. En annan vanlig ratio är 1.33:1 eller 4:3.
    • Filmens framerate är 25.
    • Ljudets format är MP4A, vilket strax kan få betydelse.
    • Ljudets bitrate är 128k.
    Håll nu ordning på dessa tal och antal.
  2. Ett ytterligare antal nuffror behöver bestämmas. För 100MB/h rekommenderar jag de följande:
    1. Audio bitrate: 96k (eller 128k för högre ljudkvalitet).
    2. Audio channels: 2 för hörlurar, annars 1 för mono.
    3. Video resolution: 240 på y-ledden, alltså 320x240 för 4:3 och 428x240 för 16:9.
    4. Video bitrate: 131.5k (eller 99.5k om du valde 128k som audio bitrate).
    5. Video framerate: 15 (alt. original/2, i mitt exempel alltså 12.5).

    Den film jag använder som exempel kommer från SVTPlay och heter film.mp4. De kodar vanligtvis sitt ljud i MP4A-format. Eftersom detta är samma format som vår färdiga mobilfilm kommer att använda, så kan vi välja att kopiera ljudströmmen istället för att koda om den. Ljudkvaliteten blir då oerhört mycket bättre, men eftersom 128k tar större plats än 96k, så måste videokvaliteten göras sämre (99.5k) om vi ska hålla oss till 100 MB/h. Jag kommer att demonstrera bägge varianterna.


  3. Nu ska vi bestämma våra rörliga parametrar. Vi har en film i 16:9-format och vill ha stereoljud i 96k. Då blir det så här:
    • Aspect ratio: -aspect 16:9
    • Video resolution: -s 428x240

    • Video bitrate: -b 131.5k

    • Video framerate: -r 15

    • Audio channels: -ac 2

    • Audio bitrate: -ab 96k


    Vill vi däremot bara kopiera den ursprungliga ljudströmmen, som ju låg på höga 128k istället för bara 96k, så byter vi videokvalitet och kan strunta i sådant som rör ljudkvalitet:

    • Aspect ratio: -aspect 16:9
    • Video resolution: -s 428x240
    • Video bitrate: -b 99.5k
    • Video framerate: -r 15

    Nu är det dags att göra bruk av parametrarna.


  4. Det går att få bättre kvalitet och mera exakt filstorlek genom att koda filmen två gånger, istället för bara en. Det tar dock dubbelt så lång tid. Vill du snabba på, så hoppa över det här steget. Annars sätter vi FFmpeg att göra en provkodning av filmen och spara statistik i ett par loggfiler. Här är trollformeln för att göra detta i Unix-liknande system:

    $ ffmpeg -i "film".mp4 -an -f mp4 -y -vcodec libx264 -flags +loop+mv4 -cmp 256 -partitions +parti4x4+parti8x8+partp4x4+partp8x8 -subq 7 -trellis 1 -refs 5 -bf 0 -flags2 +mixed_refs -coder 0 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 \
    -b 131.5k -aspect 16:9 -s 428x240 -r 15 \
    -acodec aac -ar 44100 -ab 96k -ac 2 \
    -pass 1 /dev/null

    Backslash markerar radbrytningar som inte behövs. Om du använder Windows måste du ta bort dem, både backslasharna och radbrytningarna. Dessutom måste du ersätta /dev/null med NUL.
    Om vi istället för att omkoda ljudet bara ska kopiera det, så ska näst sista raden ändras från -acodec aac -ar 44100 -ab 96k -ac 2 till bara -acodec copy, och så måste förstås -b 131.5k på raden före ändras till -b 99.5k. Ett Windows-exempel utan radmatningar:

    $ ffmpeg -i "film".mp4 -an -f mp4 -y -vcodec libx264 -flags +loop+mv4 -cmp 256 -partitions +parti4x4+parti8x8+partp4x4+partp8x8 -subq 7 -trellis 1 -refs 5 -bf 0 -flags2 +mixed_refs -coder 0 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 -b 99.5k -aspect 16:9 -s 428x240 -r 15 -acodec copy -pass 1 NUL


  5. Nu är det dags att koda själva filen. Vi bestämmer oss för att den ska heta telefonfilm.mp4. Kommandona ska se likadana ut i Windows som i andra operativsystem, såvitt jag vet. Om du inte hoppade över det föregående steget ska du göra så här:

    ffmpeg -i "film".mp4 -vcodec libx264 -flags +loop+mv4 -cmp 256 -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -subq 7 -trellis 1 -refs 5 -bf 0 -flags2 +mixed_refs -coder 0 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40-i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 -b 131.5k -aspect 16:9 -s 428x240 -r 15 -acodec aac -ar 44100 -ab 96k -ac 2 -pass 2 "telefonfilm".mp4

    Om du däremot hoppade över det, så tar du bort -pass 2 från slutet.
    Och valde du att kopiera ljudströmmen istället för att koda om den, så blir det så här:

    ffmpeg -i "film".mp4 -vcodec libx264 -flags +loop+mv4 -cmp 256 -partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -subq 7 -trellis 1 -refs 5 -bf 0 -flags2 +mixed_refs -coder 0 -me_range 16 -g 250 -keyint_min 25 -sc_threshold 40-i_qfactor 0.71 -qmin 10 -qmax 51 -qdiff 4 -b 99.5k -aspect 16:9 -s 428x240 -r 15 -acodec copy -pass 2 "telefonfilm".mp4

    Även här gäller att -pass 2 ska bort om du hoppade över det förra steget.


Nu är filmen klar. Resultatet finns i filen telefonfilm.mp4.

Andra MB/h

Om du vill ha riktigt små filmer, bara 50 MB/h, så kan du försöka dig på en upplösning om 120 i y-ledden, alltså 160x120 för 4:3 eller 214x120 för 16:9. Använd 17.75k som video bitrate och 96k för ljudet, eller 49.75k för videon och 64k för ljudet om du tycker bilden blir för dålig. Detta är uträknat så här:

17,75 + 96 = 49,75 + 64 = 113,75

Du kan givetvis försöka med någon annan kombination. Huvudsaken är att summan är 113,75.

För 75 MB/h är 106.5k lämplig videokvalitet till 64k på ljudet. Till ljud på 96k gäller 74.6k för video. Upplösningen bör vara 160 på y-ledden, vilket innebär 286x160 för 16:9, eller 208x156 (!) för 4:3.

För 150 MB/h gäller 360 på y-ledden, alltså 480x360 (4:3) eller 642x360 (16:9). En duglig kompromiss mellan ljud och bild är 213k för video och 128k för ljudet. Om bildkvaliteten är viktigast så kan du försöka dig på 245k för video och 96k för ljud. Konserter och sådant är bäst med 149k för video och 192k för ljud.

Till sist kan man koda i 200 MB/h, och därmed toppa de vanligaste pekskärmsmobilernas upplösning med 480 på y-ledden. Använd upplösningen 640x480 för 4:3. Om telefonen har en FWVGA-skärm (till exempel X10) så är 854x480 bra till 16:9, men har den bara en WVGA-skärm (som Galaxy S) så är det bättre med 800x450. Kompromisskvalitet får du med 327k video och 128k ljud. Bäst blir bilden med 359k video och 96k ljud, medan ljudet blir bäst med 263k video och 192k ljud.

Ännu bättre kvalitet är förstås möjlig. För 250 MB/h ska summan av ljud och video vara 568,75k, och för 500 MB/h är summan givetvis den dubbla: 1137,5k. Till upplösning kan du i bägge fallen använda samma som för 200 MB/h. 500 MB/h är för övrigt en sådan kvalitet att det är nästintill meningslöst att använda något annat än 192k ljud och 945.5k video. Eller ja, är du helt galen så kan du ju använda 320k ljud på 817.5k video. ;-)

Nu har jag säkert tryck- eller räknefelat någonstans i de snårigare partierna. Får du problem så löser det sig kanske i kommentarfältet.

Så, några frågor?

Kommentarer till inlägget

  1. ingvar, 23 september 2011, 05.46Gravatar

    Den här raden kan man korta betydligt:

    "(VIDEO_WIDTH|VIDEO_HEIGHT|VIDEO_FPS|AUDIO_BITRATE|AUDIO_FORMAT)"

    Till:

    "(VIDEO*|AUDIO*)"

  2. ingvar, 23 september 2011, 05.55Gravatar

    Du ska ha tack för raden:
    mplayer -frames 0 -identify "film".mp4

    Kände jag inte till.

Lämna en kommentar