FFmpeg: Come dividere il video in modo efficiente?

Vorrei tagliare video avi in due più piccoli consecutive video. Sto usando ffmpeg.

Un modo è quello di eseguire ffmpeg due volte:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi
ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi

Ma secondo la pagina di manuale di ffmpeg, posso fare di più di un file di output da un file di input utilizzando solo uno linea:

ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 output1.avi \
   -vcodec copy -acodec copy -ss 00:30:00 -t 00:30:00 output2.avi

La mia domanda è, il più tardi approccio risparmiare tempo di calcolo e di memoria?

  • così fa risparmiare tempo?
  • quando si utilizza il “-vcodec copy -acodec copy” è molto veloce:))
  • Perché non avete il tempo di entrambe le versioni (e guardare il monitor memoria come htop), e ci dicono che cosa la risposta è?
  • Il primo esempio lo fa in modo sequenziale, mentre il secondo esempio viene utilizzato il thread. Entrambi faranno la stessa cosa, senza apprezzabili speedups dovrebbe verificarsi. Ma per semplificare le cose, si potrebbe utilizzare ffmpeg flusso segmenter muxer: ffmpeg.org/…
  • Questo esempio sembra male male! Ffmpeg documentazione dice circa l’opzione-ss: “Quando viene utilizzato come input opzione (prima -mi), cerca in questo file di input per la posizione. Quando viene utilizzato come una opzione di uscita (prima di un nome di file di output), decodifica ma scarta di ingresso fino a quando il timestamp raggiungere la posizione.” Si utilizza in posizione di output, in modo che la seconda riga rifiuti sforzo di decodifica e scartando i primi 30 minuti.
  • Se si utilizza MP4, prendere in considerazione MP4Box -split MP4Box -split 5 input.mp4 di dividere ogni 5 secondi. Disponibili anche opzioni per dividere ogni x byte.
  • Se TS contenere più di un programma (i programmi TV che catturato dal DVB-T), come si può dividere? Io per esempio ho un file TS che contengono calcio + cucina + cartone animato .Come posso dividere questo file TS 3 file mpg?
  • ma utilizzando -ss come opzione di input nella seconda divisione potrebbe non essere accurata, così si potrebbe non ottenere una pulizia split. IMO l’esempio da OP è più corretto.

InformationsquelleAutor Antony | 2011-04-13

 

10 Replies
  1. 79

    Ffmpeg wiki link a questa pagina in riferimento a “Come dividere il video in modo efficiente”. Io non sono convinto di questa pagina risponde a questa domanda, così ho fatto come @AlcubierreDrive suggerito…

    echo "Two commands" 
    time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 -sn test1.mkv
    time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test2.mkv
    echo "One command" 
    time ffmpeg -v quiet -y -i input.ts -vcodec copy -acodec copy -ss 00:00:00 -t 00:30:00 \
      -sn test3.mkv -vcodec copy -acodec copy -ss 00:30:00 -t 01:00:00 -sn test4.mkv
    

    Che uscite…

    Two commands
    real    0m16.201s
    user    0m1.830s
    sys 0m1.301s
    
    real    0m43.621s
    user    0m4.943s
    sys 0m2.908s
    
    One command
    real    0m59.410s
    user    0m5.577s
    sys 0m3.939s
    

    Ho provato una SD & file HD, dopo un paio di piste & un po ‘ di matematica.

    Two commands SD 0m53.94 #2 wins  
    One command  SD 0m49.63  
    
    Two commands SD 0m55.00  
    One command  SD 0m52.26 #1 wins 
    
    Two commands SD 0m58.60 #2 wins  
    One command  SD 0m58.61 
    
    Two commands SD 0m54.60  
    One command  SD 0m50.51 #1 wins 
    
    Two commands SD 0m53.94  
    One command  SD 0m49.63 #1 wins  
    
    Two commands SD 0m55.00  
    One command  SD 0m52.26 #1 wins 
    
    Two commands SD 0m58.71  
    One command  SD 0m58.61 #1 wins
    
    Two commands SD 0m54.63  
    One command  SD 0m50.51 #1 wins  
    
    Two commands SD 1m6.67s #2 wins  
    One command  SD 1m20.18  
    
    Two commands SD 1m7.67  
    One command  SD 1m6.72 #1 wins
    
    Two commands SD 1m4.92  
    One command  SD 1m2.24 #1 wins
    
    Two commands SD 1m1.73  
    One command  SD 0m59.72 #1 wins
    
    Two commands HD 4m23.20  
    One command  HD 3m40.02 #1 wins
    
    Two commands SD 1m1.30  
    One command  SD 0m59.59 #1 wins  
    
    Two commands HD 3m47.89  
    One command  HD 3m29.59 #1 wins  
    
    Two commands SD 0m59.82  
    One command  SD 0m59.41 #1 wins  
    
    Two commands HD 3m51.18  
    One command  HD 3m30.79 #1 wins  
    

    File in SD = 1.35 GB DVB (transport stream)

    File HD = 3.14 GB DVB transport stream

    Conclusione

    L’unico comando è meglio, se si sta gestendo HD, concorda con i manuali commenti sull’uso -ss dopo che il file di input per fare un ‘lenta di ricerca’. SD i file hanno una differenza trascurabile.

    Le due versione del comando dovrebbe essere più veloce aggiungendo un altro -ss prima che il file di input per il ‘fast cercare’, seguito dal più accurata lenta cercare.

    • Se TS contenere più di un programma (i programmi TV che catturato dal DVB-T), come si può dividere? Io per esempio ho un file TS che contengono calcio + cucina + cartone animato .Come posso dividere questo file TS 3 file mpg?
    • Ho usato la tua risposta nella mia domanda qui (stackoverflow.com/questions/41983940/…), ma non ha funzionato, che cosa pensi che sto facendo di sbagliato?
    • Il risultato è stato senza video (solo audio) nel mio caso. Dopo alcuni esperimenti ho trovato soultion. È necessario specificare la chiave per non modificare la qualità” come questo -q:v 0.
  2. 19

    Ecco un utile script, che consente di dividere automaticamente: Uno script per la divisione video con ffmpeg

    #!/bin/bash
     
    # Written by Alexis Bezverkhyy <[email protected]> in 2011
    # This is free and unencumbered software released into the public domain.
    # For more information, please refer to <http://unlicense.org/>
     
    function usage {
            echo "Usage : ffsplit.sh input.file chunk-duration [output-filename-format]"
            echo -e "\t - input file may be any kind of file reconginzed by ffmpeg"
            echo -e "\t - chunk duration must be in seconds"
            echo -e "\t - output filename format must be printf-like, for example myvideo-part-%04d.avi"
            echo -e "\t - if no output filename format is given, it will be computed\
     automatically from input filename"
    }
     
    IN_FILE="$1"
    OUT_FILE_FORMAT="$3"
    typeset -i CHUNK_LEN
    CHUNK_LEN="$2"
     
    DURATION_HMS=$(ffmpeg -i "$IN_FILE" 2>&1 | grep Duration | cut -f 4 -d ' ')
    DURATION_H=$(echo "$DURATION_HMS" | cut -d ':' -f 1)
    DURATION_M=$(echo "$DURATION_HMS" | cut -d ':' -f 2)
    DURATION_S=$(echo "$DURATION_HMS" | cut -d ':' -f 3 | cut -d '.' -f 1)
    let "DURATION = ( DURATION_H * 60 + DURATION_M ) * 60 + DURATION_S"
     
    if [ "$DURATION" = '0' ] ; then
            echo "Invalid input video"
            usage
            exit 1
    fi
     
    if [ "$CHUNK_LEN" = "0" ] ; then
            echo "Invalid chunk size"
            usage
            exit 2
    fi
     
    if [ -z "$OUT_FILE_FORMAT" ] ; then
            FILE_EXT=$(echo "$IN_FILE" | sed 's/^.*\.\([a-zA-Z0-9]\+\)$/\1/')
            FILE_NAME=$(echo "$IN_FILE" | sed 's/^\(.*\)\.[a-zA-Z0-9]\+$/\1/')
            OUT_FILE_FORMAT="${FILE_NAME}-%03d.${FILE_EXT}"
            echo "Using default output file format : $OUT_FILE_FORMAT"
    fi
     
    N='1'
    OFFSET='0'
    let 'N_FILES = DURATION /CHUNK_LEN + 1'
     
    while [ "$OFFSET" -lt "$DURATION" ] ; do
            OUT_FILE=$(printf "$OUT_FILE_FORMAT" "$N")
            echo "writing $OUT_FILE ($N/$N_FILES)..."
            ffmpeg -i "$IN_FILE" -vcodec copy -acodec copy -ss "$OFFSET" -t "$CHUNK_LEN" "$OUT_FILE"
            let "N = N + 1"
            let "OFFSET = OFFSET + CHUNK_LEN"
    done
    
    • Stesso commento vale per te come per SEARAS. La scrittura di file batch è utile quando è assolutamente necessario e quando non si hanno altre possibilità, perché non è portabile. Non sarà in grado di eseguire lo stesso script su Windows, per esempio. Quando ci sono più generico/portatile modi, script batch deve essere evitato, per risparmiare il tempo necessario per porto essi. Dal ffmpeg ha più modi per risolvere questo problema, il modo corretto sarebbe quello di utilizzare ffmpeg da solo, senza l’aiuto di script.
    • Bello script. Lo ha scritto? È su GitHub? Vorrei dare qualche suggerimento 🙂
    • per mp4, le scene sono danneggiati. meglio sostituire copia con: -vcodec libx264 -acodec aac
  3. 5

    Nella mia esperienza, non usare ffmpeg per dividere/unire.
    MP4Box, è più veloce e leggero di ffmpeg. Si prega di tryit.
    Ad esempio, se si desidera dividere un 1400mb file MP4 in due parti, una 700mb è possibile utilizzare i seguenti cmdl:
    MP4Box -splits 716800 input.mp4
    ad esempio, per la concatenazione di due file, che è possibile utilizzare:

    MP4Box -cat file1.mp4 -cat file2.mp4 output.mp4
    

    O se avete bisogno di dividere il tempo, utilizzare -splitx StartTime:EndTime:

    MP4Box -add input.mp4 -splitx 0:15 -new split.mp4

    • Questo era esattamente quello che mi serviva! Quando ero taglio con ffmpeg, la clip non si avvia su fotogrammi chiave ed era strano blocca alle estremità. Utilizzando MP4Box -splitz ha fatto il trucco!
    • come posso tagliare il video utilizzando Mp4Box, con più numeri? per esempio ho bisogno di avere sub clip in pochi secondi sono : 5 – 8 , 21 – 30 , 12 – 18 quindi ho bisogno di tre file di output video.
    • Aggiorno la risposta :-).
    • Ed è molto più facile da usare EndTime di -t.
  4. 1

    il successivo approccio risparmiare tempo di calcolo e di memoria?

    Non c’è grande differenza tra i due esempi che hai fornito. Il primo esempio di tagli il video in sequenza, a 2 passi, mentre il secondo esempio non è allo stesso tempo (l’uso dei thread). Nessun particolare speed-up sarà evidente. Si può leggere di più su creazione di uscite multiple con FFmpeg

    Più ulteriormente più, che cosa si può utilizzare (negli ultimi FFmpeg) è il stream segmenter muxer che può:

    flussi di output per un certo numero di file di quasi fisso durata. Nome del file di Output modello può essere impostato in modo simile a immagine2.

  5. 1

    Qui è un semplice Windows file bat per dividere il file in arrivo in 50 parti. Ogni parte ha una lunghezza di 1 minuto. Ci dispiace per stupido script. Spero che sia meglio avere un muto di script di windows invece che non hanno affatto. Forse può aiutare qualcuno.
    (Basato su “file bat per il ciclo” da questo sito.)

    set var=0
    @echo off
    :start
    set lz=
    if %var% EQU 50 goto end
    if %var% LEQ 9 set lz=0
    echo part %lz%%var%
    ffmpeg -ss 00:%lz%%var%:00 -t 00:01:00 -i %1 -acodec copy -vcodec copy %2_%lz%%var%.mp4
    set /a var+=1
    goto start
    
    :end
    echo var has reached %var%.
    exit
    
    • Questo è essenzialmente il primo frammento di codice nella domanda (consecutivi ffmpeg comandi) riscritto come un loop. Questo non risponde alla domanda di se questo approccio o un singolo comando “salva tempo di calcolo e di memoria”.
  6. 0

    Non prova ist, ma questo sembra promettente:

    Basic stream segmenter

    Non è, ovviamente, dividere file AVI in segmenti di uguale dimensione, il che implica che questi blocchi non perdere qualità o aumentare la memoria o deve essere ricalcolato.

    Si utilizza anche il codec copia – significa che è in grado di gestire molto grandi flussi ? Perché questo è il mio problema, voglio abbattere i miei avi così ho potuto usare un filtro per sbarazzarsi di distorsione. Ma un intero avi funziona per ore.

  7. -1

    Qui è un modo perfetto per dividere il video. L’ho fatto in precedenza, e funziona bene per me.

    ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4 (Per cmd).
    shell_exec('ffmpeg -i C:\xampp\htdocs\videoCutting\movie.mp4 -ss 00:00:00 -t 00:00:05 -async 1 C:\xampp\htdocs\videoCutting\SampleVideoNew.mp4') (php).

    Si prega di seguire questo e sono sicuro che funzionerà perfettamente.

    • Perché è questo il modo perfetto” per dividere il video? Come la riga di comando in questione, si sta passando -i seguita da -ss e -t. La domanda è su come in modo efficiente estrarre segmenti multipli dallo stesso file di input, anche se, considerando che vi sono solo l’estrazione di un singolo segmento. Non vedo come questo risponde alla domanda.
  8. -2

    un modo semplice è quello di utilizzare opzione trim con publitio url-based api.

    una volta a ottenere il vostro video caricato, basta impostare l’offset iniziale e finale offset url (so_2,eo_2) così:

        https://media.publit.io/file/so_2,eo_2/tummy.mp4
    

    questo crea istantaneamente nuove video a partire dal 2 secondi e 2 secondi di lunghezza. è possibile dividere i video in questo modo comunque ti piace.

    • La domanda chiede quale è più efficiente di due metodi di estrazione più segmenti di un file di input con ffmpeg. A meno che non si dispone di un collegamento internet veloce, penso di avere a caricare tutto il video a un servizio cloud e quindi scarica i risultati sta per aumentare il tempo di elaborazione in modo significativo. Anche così, questo continua a non rispondere alla domanda su quale approccio con ffmpeg è più efficiente.
  9. -7

    Si scopre che la dimensione del file(s) in caso di successivo sarebbe proporzionalmente equivalente di una fetta di tempo.

    • Non so se questo risponde alla domanda il richiedente posti: egli è preoccupato per i tempi di calcolo e di memoria, non la dimensione del file.

Lascia un commento