Como concatenar dois arquivos flv?

15

Quero concatenar dois arquivos flv (baixados do Youtube.com) pelas ferramentas de linha de comando do Linux.
O ffmpegtutorial é muito complicado, então eu tentei o mencodetutorial .
Mas eu recebo uma saída vazia. Não sei como resolver o problema.

ffmpeg -i input_1.flv

ffmpeg version 0.8.1-4:0.8.1-0ubuntu1, Copyright (c) 2000-2011 the Libav developers
  built on Mar 22 2012 05:29:10 with gcc 4.6.3
This program is not developed anymore and is only provided for compatibility. Use avconv instead (see Changelog for the list of incompatible changes).
[flv @ 0x89faaa0] Estimating duration from bitrate, this may be inaccurate

Seems stream 0 codec frame rate differs from container frame rate: 59.94 (2997/50) -> 29.97 (30000/1001)
Input #0, flv, from 'input_1.flv':
  Metadata:
    starttime       : 0
    totalduration   : 173
    totaldatarate   : 457
    bytelength      : 9874241
    canseekontime   : true
    sourcedata      : B4A7D6704MH1334385311768958
    purl            : 
    pmsg            : 
  Duration: 00:02:52.83, start: 0.000000, bitrate: 459 kb/s
    Stream #0.0: Video: h264 (Main), yuv420p, 640x360 [PAR 1:1 DAR 16:9], 360 kb/s, 29.97 tbr, 1k tbn, 59.94 tbc
    Stream #0.1: Audio: aac, 44100 Hz, stereo, s16, 99 kb/s
At least one output file must be specified

ffmpeg -i input_2.flv

ffmpeg version 0.8.1-4:0.8.1-0ubuntu1, Copyright (c) 2000-2011 the Libav developers
  built on Mar 22 2012 05:29:10 with gcc 4.6.3
This program is not developed anymore and is only provided for compatibility. Use avconv instead (see Changelog for the list of incompatible changes).
[flv @ 0x85b7aa0] Estimating duration from bitrate, this may be inaccurate

Seems stream 0 codec frame rate differs from container frame rate: 59.94 (2997/50) -> 29.97 (30000/1001)
Input #0, flv, from 'input_2.flv':
  Metadata:
    starttime       : 0
    totalduration   : 488
    totaldatarate   : 254
    bytelength      : 15467674
    canseekontime   : true
    sourcedata      : BADC21903MH1334385484128583
    purl            : 
    pmsg            : 
  Duration: 00:08:07.54, start: 0.000000, bitrate: 250 kb/s
    Stream #0.0: Video: h264 (Main), yuv420p, 640x360 [PAR 1:1 DAR 16:9], 151 kb/s, 29.97 tbr, 1k tbn, 59.94 tbc
    Stream #0.1: Audio: aac, 44100 Hz, stereo, s16, 99 kb/s
At least one output file must be specified

mencoder -of lavf -oac copy -ovc copy -o output.flv input_1.flv input_2.flv

MEncoder svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team
success: format: 0  data: 0x0 - 0x96ab41
libavformat version 53.21.0 (external)
Mismatching header version 53.19.0
libavformat file format detected.
[flv @ 0xb6b09d80]Estimating duration from bitrate, this may be inaccurate
[lavf] stream 0: video (h264), -vid 0
[lavf] stream 1: audio (aac), -aid 0
VIDEO:  [H264]  640x360  0bpp  29.970 fps  360.0 kbps (43.9 kbyte/s)
[V] filefmt:44  fourcc:0x34363248  size:640x360  fps:29.970  ftime:=0.0334
** MUXER_LAVF *****************************************************************
REMEMBER: MEncoder's libavformat muxing is presently broken and can generate
INCORRECT files in the presence of B-frames. Moreover, due to bugs MPlayer
will play these INCORRECT files as if nothing were wrong!
*******************************************************************************
OK, exit.
videocodec: framecopy (640x360 0bpp fourcc=34363248)
Audio format 0x4134504d is incompatible with '-oac copy', please try '-oac pcm' instead or use '-fafmttag' to override it.

Exiting...

mencoder -of lavf -oac pcm -ovc copy -o output.flv input_1.flv input_2.flv

MEncoder svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team
success: format: 0  data: 0x0 - 0x96ab41
libavformat version 53.21.0 (external)
Mismatching header version 53.19.0
libavformat file format detected.
[flv @ 0xb6bb6d80]Estimating duration from bitrate, this may be inaccurate
[lavf] stream 0: video (h264), -vid 0
[lavf] stream 1: audio (aac), -aid 0
VIDEO:  [H264]  640x360  0bpp  29.970 fps  360.0 kbps (43.9 kbyte/s)
[V] filefmt:44  fourcc:0x34363248  size:640x360  fps:29.970  ftime:=0.0334
==========================================================================
Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders
libavcodec version 53.35.0 (external)
Mismatching header version 53.32.2
AUDIO: 44100 Hz, 2 ch, s16le, 99.0 kbit/7.02% (ratio: 12376->176400)
Selected audio codec: [ffaac] afm: ffmpeg (FFmpeg AAC (MPEG-2/MPEG-4 Audio))
==========================================================================
** MUXER_LAVF *****************************************************************
REMEMBER: MEncoder's libavformat muxing is presently broken and can generate
INCORRECT files in the presence of B-frames. Moreover, due to bugs MPlayer
will play these INCORRECT files as if nothing were wrong!
*******************************************************************************
OK, exit.
videocodec: framecopy (640x360 0bpp fourcc=34363248)
VIDEO CODEC ID: 28
AUDIO CODEC ID: 2e, TAG: 0
Writing header...
[flv @ 0xb6bb6d80]Codec for stream 0 does not use global headers but container format requires global headers
[flv @ 0xb6bb6d80]Codec for stream 1 does not use global headers but container format requires global headers
[NULL @ 0xb6472380]codec not compatible with flv
Floating point exception (core dumped)

stat output.flv

  File: `output.flv'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 700h/1792d  Inode: 1722857     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1000/     kev)   Gid: ( 1000/     kev)
Access: 2012-05-04 10:44:45.153319669 +0800
Modify: 2012-05-04 10:44:45.153319669 +0800
Change: 2012-05-04 10:44:45.153319669 +0800
 Birth: -
kev
fonte
mencoder -forceidx -of lavf -oac copy -ovc copy -o output.flv clip1.flv clip2.flv clip3.flv fonte
Sebastian

Respostas:

11

Eu pessoalmente faria isso com o ffmpeg's

Concat desmuxer

Primeiro, crie um arquivo chamado inputs.txtque se parece com isso:

file 'input1.flv'
file 'input2.flv'

Em seguida, use ffmpeg da seguinte maneira:

ffmpeg -f concat -i inputs.txt -c copy output.mp4

(Você pode usar output.flv, embora o MP4 seja geralmente um formato mais útil). O desmuxer está disponível nas versões do ffmpeg a partir da 1.1. Se você quiser manter uma versão desatualizada do ffmpeg por algum motivo, poderá usar o

Protocolo Concat

Isso é um pouco complicado. O contêiner FLV não oferece suporte à concatenação no nível do arquivo, portanto, você precisará remuxar para um contêiner que sim - como um MPEG Transport Stream. Infelizmente, com o vídeo h.264 e o áudio AAC, você precisará aplicar alguns filtros de fluxo de bits.

Como você está no Linux, você pode usar pipes nomeados.

mkfifo temp0 temp1

Você precisará fazer o seguinte em três janelas temporais separadas (ou abas, se o emulador de terminal suportá-las - ctrl+shift+tnormalmente abre uma nova aba):

ffmpeg -i input0.flv -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0

ffmpeg -i input1.flv -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1

ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4

De fato, você pode executar todos eles em uma linha de comando (de aparência bastante complicada):

ffmpeg -i input0.flv -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp0 2> /dev/null & \
ffmpeg -i input1.flv -map 0 -c copy -f mpegts -bsf h264_mp4toannexb -y temp1 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4

Certifique-se de que output.mp4 ainda não exista, isso não funcionará. Se alguém está lendo isso, está em um sistema que não suporta pipes nomeados, eles precisam usar:

ffmpeg -i input0.flv -map 0 -c copy -f mpegts -bsf h264_mp4toannexb temp0.ts
ffmpeg -i input1.flv -map 0 -c copy -f mpegts -bsf h264_mp4toannexb temp1.ts
ffmpeg -i "concat:temp0.ts|temp1.ts" -c copy -absf aac_adtstoasc output.mp4

Isso criará um par de arquivos intermediários chamados temp0.ts e temp1.ts, que podem ser destruídos com segurança quando você terminar.

Observe que essas instruções funcionarão para os arquivos FLV especificados no OP, e provavelmente a maioria dos FLVs modernos da Internet, uma vez que quase universalmente usam vídeo h264 e áudio aac. Para outros codecs, essas instruções terão que ser um pouco ajustadas.

evilsoup
fonte
Resposta fantástica! Esta foi a única maneira que consegui mesclar FLV sem gravar o vídeo.
Neu242 07/07
1
@DaveJarvis você provavelmente está usando uma versão antiga do ffmpeg (como as fornecidas nos repositórios das principais distribuições Linux). Do seu comentário para outra das minhas respostas, acho que você está usando o Debian ou o Ubuntu (ou um derivado), que nem sequer contém o ffmpeg real, mas uma versão falsa e deliberadamente aleijada da equipe libav (devido a algumas desagradáveis política de bifurcação de projetos). Tente com uma versão estática do ffmpeg a partir daqui ou compile sua própria seguindo as instruções no wiki do ffmpeg .
evilsoup
2

Você insiste em usar o formato FLV? você pode convertê-los para mpg ou outros formatos (consulte isso ) e depois se juntar a eles (consulte isso ).

ou pode ser, você pode apenas tentar o método de junção diretamente nos arquivos flv.

EDITAR

Leia isto ou isto . Ele usa alguns parâmetros diferentes para o MEncoder.

tumchaaditya
fonte
Obrigado. Mas é preciso mais espaço em disco para armazenar arquivos mpg. E leva muito tempo para a codificação. Quero concat dois arquivos flv e corrigir o cabeçalho.
Kev
Está bem. o método de junção no meu link funciona com arquivos flv? (o método "cat").
Tumchaaditya
1

Encontrei um pacote python: http://pypi.python.org/pypi/vnc2flv/


flvcat.py

flvcat.pyé um programa de edição simplista para um filme FLV. Ele suporta a concatenação de vários filmes, o recorte do tamanho do quadro de um filme, a nova amostragem de um filme em um tamanho menor com o pan automático, etc.

flvcat.py [options] src1[:ranges1] src2[:ranges2] ... output 

Para cada arquivo de filme, você pode recortar as partes do filme a serem adicionadas especificando seus intervalos. Intervalos é uma lista hifenizada e separada por vírgula de milissegundos. Por exemplo,

out.flv:10000-20000 

significa um clipe de 10 segundos de filme out.flv (0: 10-0: 20). A especificação de apenas um final do intervalo também é suportada:

out.flv:10000- 

significa o filme inteiro, exceto os primeiros 10 segundos. Quando os intervalos são omitidos, o filme inteiro é usado.

Exemplos:

$ flvcat.py movie1.flv movie2.flv output.flv
(Concatenate movie1.flv and movie2.flv and save it as output.flv)

$ flvcat.py -W 640x480 movie1.flv output.flv
(Resize the movie1.flv with auto-panning with its window size 640x480 and save it as output.flv)

$ flvcat.py movie1.flv:15000-30000 output.flv
(Clip the part of movie1.flv from 0:15 to 0:30 and save it as output.flv)

$ flvcat.py movie1.flv:2500- output.flv
(Chop the first 2.5 seconds off and save it as output.flv)

Opções:

-r fps
    Specifies the number of frames per second. (default: 15) 
-K keyframe
    Specifies the rate of key frames that is inserted in every this number of frames. (default: every 150 frames) 
-B blocksize
    Specifies the block size. (default: 32) 
-C wxh{+|-}x{+|-}y
    Specifies the clipping. (default: entire frame) 
-W wxh
    Specifies the window size for auto panning. Auto panning tracks the changes in the screen and tries to focus on the active part of the screen. This helps reducing the movie screen size. (default: no auto panning) 
-S speed
    Specifies the speed of auto panning. (default: 60 frames) 
-f
    Forces overwriting the output file. 
kev
fonte