Twitch tem um post sobre isso. Eles explicam que decidiram usar seu próprio programa por vários motivos; uma delas era que o ffmpeg não permite executar diferentes instâncias x264 em diferentes threads, mas dedica todos os threads especificados a um quadro em uma saída antes de passar para a próxima saída.
Se você não estiver transmitindo em tempo real, terá mais luxo. A maneira 'correta' provavelmente é codificar em uma resolução com apenas o tamanho GOP especificado com -g e, em seguida, codificar as outras resoluções forçando quadros-chave nos mesmos locais.
Se você quiser fazer isso, use o ffprobe para obter os tempos do quadro-chave e, em seguida, use um script de shell ou uma linguagem de programação real para convertê-lo em um comando ffmpeg.
Mas, para a maioria dos conteúdos, há pouca diferença entre ter um quadro-chave a cada 5 segundos e dois quadros-chave a cada 5 segundos (um forçado e outro do scenecut). Trata-se do tamanho médio do quadro I versus o tamanho dos quadros P e quadros B. Se você usa x264 com configurações típicas (a única razão pela qual acho que você deve fazer algo para afetá-las é se você definir -qmin, como uma maneira pobre de impedir que x264 use taxa de bits em conteúdo fácil; isso limita todos os tipos de quadro ao mesmo valor , Acho) e obtenha um resultado como o tamanho médio do quadro I de 46 kB, o quadro P 24 kB, o quadro B 17 kB (metade da frequência dos quadros P) e, em seguida, um quadro I extra a cada segundo a 30 fps é apenas um aumento de 3% no tamanho do arquivo. A diferença entre h264 e h263 pode ser composta por um monte de reduções de 3%, mas uma única não é muito importante.
Em outros tipos de conteúdo, os tamanhos dos quadros serão diferentes. Para ser justo, trata-se de complexidade temporal e não espacial, por isso não é apenas um conteúdo fácil versus um conteúdo rígido. Mas, geralmente, os sites de streaming de vídeo têm um limite de taxa de bits e o conteúdo com quadros I relativamente grandes é um conteúdo fácil que será codificado com alta qualidade, independentemente de quantos quadros-chave extras sejam adicionados. É um desperdício, mas esse desperdício geralmente não será percebido. O caso mais inútil é provavelmente um vídeo que é apenas uma imagem estática que acompanha uma música, onde cada quadro-chave é exatamente o mesmo.
Uma coisa que não tenho certeza é como os quadros-chave forçados interagem com o limitador de taxa definido com -maxrate e -bufsize. Acho que até o YouTube teve problemas recentes ao definir corretamente as configurações do buffer para fornecer qualidade consistente. Se você estiver usando apenas configurações médias de taxa de bits, como pode ser visto em alguns sites (já que você pode inspecionar as opções do x264 no cabeçalho / mov atom? Com um editor hexadecimal), o modelo do buffer não é um problema, mas se você exibindo conteúdo gerado pelo usuário, a taxa de bits média incentiva os usuários a adicionar uma tela preta no final do vídeo.
A opção -f do Ffmpeg, ou qualquer outra opção de codificador usada, é mapeada para a opção específica do codificador. Portanto, '-x264-params keyint = GOPSIZE' é equivalente a '-g GOPSIZE'.
Um problema com o uso da detecção de cena é se você prefere quadros-chave próximos a números específicos por qualquer motivo. Se você especificar quadros-chave a cada 5 segundos e usar a detecção de cena, e houver uma alteração de cena em 4,5, ela deverá ser detectada, mas o próximo quadro-chave será em 9,5. Se o tempo continuar aumentando assim, você poderá terminar com quadros-chave em 42,5, 47,5, 52,5 etc., em vez de 40, 45, 50, 55. Por outro lado, se houver uma mudança de cena em 5,5, haverá um quadro-chave em 5 e 5,5 será muito cedo para outro. O Ffmpeg não permite que você especifique "faça um quadro-chave aqui se não houver mudança de cena nos próximos 30 quadros". Alguém que entende C pode adicionar essa opção, no entanto.
Para vídeo com taxa de quadros variável, quando não estiver transmitindo ao vivo como o Twitch, você poderá usar as mudanças de cena sem converter permanentemente em taxa de quadros constante. Se você usar o filtro 'select' no ffmpeg e usar a constante 'scene' na expressão, a saída de depuração (-v debug ou pressione '+' várias vezes durante a codificação) exibirá o número de alteração da cena. Provavelmente, isso é diferente e não é tão útil quanto o número usado por x264, mas ainda pode ser útil.
O procedimento, então, provavelmente seria fazer um vídeo de teste apenas para alterações no quadro-chave, mas talvez pudesse ser usado para dados de controle de taxa, se estiver usando 2 passagens. (Não tenho certeza se os dados gerados são úteis para diferentes resoluções e configurações; os dados da árvore de macroblocos não serão.) Converta-os em vídeo com taxa de quadros constante, mas veja este bug sobre a interrupção da produção ao reduzir pela metade a taxa de quadros, se você decidir para usar o filtro fps para outros fins. Execute o x264 com o quadro-chave desejado e as configurações de GOP.
Em seguida, use esses tempos de quadro-chave com o vídeo de taxa de quadros variável original.
Se você permitir conteúdo maluco gerado pelo usuário com um intervalo de 20 segundos entre os quadros, para a codificação de taxa de quadros variável, poderá dividir a saída, usar o filtro fps, de alguma forma usar o filtro de seleção (talvez crie uma expressão realmente longa que tenha a cada momento do quadro-chave) ... ou talvez você possa usar o vídeo de teste como entrada e decodificar apenas quadros-chave, se essa opção ffmpeg funcionar, ou usar o filtro selecionar para selecionar quadros-chave. Em seguida, redimensione-o para o tamanho correto (há até um filtro scale2ref para isso) e sobreponha o vídeo original. Em seguida, use o filtro de intercalação para combinar esses quadros-chave a serem forçados com o vídeo original. Se isso resultar em dois quadros separados por 0,001 s que o filtro de intercalação não impede, então resolva esse problema com outro filtro de seleção. Lidar com os limites do buffer de quadro para o filtro de intercalação pode ser o principal problema aqui. Tudo isso poderia funcionar: use algum tipo de filtro para proteger o fluxo mais denso (filtro fifo?); consulte o arquivo de entrada várias vezes para que seja decodificado mais de uma vez e os quadros não precisem ser armazenados; use o filtro 'streamselect', o que eu nunca fiz, exatamente nos horários dos quadros-chave; melhore o filtro de intercalação alterando seu comportamento padrão ou adicionando uma opção para gerar o quadro mais antigo em um buffer em vez de soltar um quadro. o que nunca fiz, exatamente nos momentos dos quadros-chave; melhore o filtro de intercalação alterando seu comportamento padrão ou adicionando uma opção para gerar o quadro mais antigo em um buffer em vez de soltar um quadro. o que nunca fiz, exatamente nos momentos dos quadros-chave; melhore o filtro de intercalação alterando seu comportamento padrão ou adicionando uma opção para gerar o quadro mais antigo em um buffer em vez de soltar um quadro.