Pergunta

Eu deveria fornecer aos meus usuários uma maneira realmente simples de capturar videoclipes da janela principal do meu aplicativo OpenGL. Estou pensando em adicionar botões e/ou atalhos de teclado para iniciar e interromper a captura; Ao começar, eu poderia pedir um nome de arquivo e outras opções, se houver. Ele tem que ser executado no Windows (XP/Vista), mas eu também não gostaria de fechar a porta do Linux, que até agora consegui me manter aberta.

O aplicativo usa programas de fragmento e shader do OpenGL, os efeitos pelos quais eu absolutamente preciso ter nos vídeos eventuais.

Parece -me que pode haver várias abordagens diferentes que possam atender aos meus requisitos (mas eu realmente não sei por onde devo começar):

  • Uma biblioteca de codificação com funções como Startrecording (nome do arquivo), StopRecording e CaptureFrame. Eu poderia ligar para CaptureFrame () após cada quadro renderizado (ou cada segundo/terceiro/o que for). Se isso torna meu programa mais lento, não é realmente um problema.

  • Um programa externo independente que pode ser controlado programaticamente a partir do meu aplicativo. Afinal, um programa independente que pode não Seja controlado quase faz o que eu preciso ... mas, como dito, deve ser realmente simples para os usuários operarem, e eu também apreciaria a perfeição; Meu aplicativo normalmente é executado em tela cheia. Além disso, deve ser possível distribuir como parte do pacote de instalação para o meu aplicativo, que atualmente preparo usando o NSIS.

  • Use a API do Windows para capturar capturas de tela de quadro a quadro e, em seguida, empregue (por exemplo) um dos Bibliotecas mencionadas aqui. Parece ser fácil o suficiente encontrar exemplos de como capturar capturas de tela no Windows; No entanto, eu adoraria uma solução que realmente não me força a colocar minhas mãos super-sinceras no nível Winapi.

  • Use o OpenGL para renderizar em um destino fora da tela e, em seguida, use uma biblioteca para produzir o vídeo. Não sei se isso é possível, e receio que não seja o caminho de menor dor de qualquer maneira. Em particular, eu não gostaria da renderização real de seguir um caminho de execução diferente, dependendo se o vídeo está sendo capturado ou não. Além disso, eu evitaria qualquer coisa que possa diminuir a taxa de quadros no modo normal e sem captura.

Se a solução fosse livre em ambos os sentidos da palavra, isso seria ótimo, mas não é realmente um requisito absoluto. Em geral, quanto menos inchaço, melhor. Por outro lado, por razões além dessa pergunta, não posso vincular nenhum código somente GPL, infelizmente.

Em relação ao formato de arquivo, não posso esperar que meus usuários comecem a pesquisar no Google para qualquer codecs, mas enquanto também exibindo Os vídeos são fáceis o suficiente para um usuário do Windows de nível básico, eu realmente não me importo com o que é o formato. No entanto, seria ótimo se fosse possível controlar a qualidade da compressão da saída.

Só para esclarecer: eu não Precisa capturar vídeos de um dispositivo externo como a câmera de vídeo, nem estou realmente interessado em movimentos de mouse, mesmo que obtê -los também não prejudique. Não há requisitos em relação ao áudio; O aplicativo não faz barulho.

Eu escrevo C ++ usando o Visual Studio 2008, pois este aplicativo também se beneficia de Glut e Glui. Eu tenho um entendimento sólido sobre o C ++ e a vinculação nas bibliotecas e esse tipo de coisa, mas, por outro lado, o OpenGL é bastante novo para mim: até agora, eu realmente só aprendi os bits necessários para realmente fazer meu trabalho.

Eu não preciso de uma solução super-urgentemente, então fique à vontade para levar o seu tempo :)

Foi útil?

Solução

Existem duas perguntas diferentes aqui - como pegar quadros de um aplicativo OpenGL e como transformá -los em um arquivo de filme.

A primeira pergunta é fácil o suficiente; Você apenas pega cada quadro com GlReadPixels () (via PBO se precisar do desempenho).

A segunda pergunta é um pouco mais difícil, pois as soluções de plataforma cruzada (FFMPEG) tendem a ser GPL'd ou LGPL'd. O LGPL é aceitável para o seu projeto? A maneira do Windows de fazer isso (DirectShow) é um pouco de dor de cabeça para usar.

Editar: Como LGPL está ok e você pode usar o FFMPEG, veja aqui Para um exemplo de como codificar o vídeo.

Outras dicas

este Parece bastante relevante para se fundir em um Avi (como sugerido por Andrew), no entanto, eu realmente esperava evitar o LPbitmapinfoHeaders etc.

Obrigado pelas respostas, relatarei o sucesso se houver algum :)

Enquanto isso, dicas adicionais para codificar os quadros brutos de glReadPixels em videoclipes seriam apreciados.

Editar: Até agora, o FFMPEG sugerido por Mike F parece ser o caminho a percorrer. No entanto, ainda não entrei na implementação real, mas espero que isso mude no futuro próximo!

A opção mais fácil salvará cada quadro renderizado de dentro do seu aplicativo e, em seguida, mesclá -los em um AVI. Quando você tem o AVI, existem muitas bibliotecas disponíveis que podem convertê -lo em um formato mais ideal ou possivelmente pular a etapa AVI.

Em termos de obtenção de cada quadro, você pode realizar isso, renderizando uma textura fora da tela como sugere ou usando o backbuffer diretamente como fonte se o seu hardware suportar isso. Fazer qualquer um deles (e salvar cada quadro) será difícil sem uma penalidade pesada em quadros.

O fornecimento do seu aplicativo é determinístico, você pode "registrar" as ações dos usuários como uma série de entradas e, em seguida, ter um modo de exportação que os renderize sequencialmente a uma superfície fora da tela para gerar o AVI.

Eu tive que criar um projeto de demonstração de gravar uma renderização do OpenGL em um vídeo. eu usei glReadPixels Para obter os dados do pixel e criar o vídeo com o OpenCV's cvWriteFrame. O OpenCV permite que você escreva no Divx ou mesmo x264/vp8 (com ffmpeg compilado).

Eu tenho uma redação mais detalhada na minha postagem de blog junto com um projeto de amostra.http://tommy.chheng.com/2013/09/09/encode-opengl-to-video-with-opencv/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top