sábado, 25 de outubro de 2014

Alterar volume de áudio com FFmpeg

Abaixar ou aumentar o volume de um áudio usando o FFmpeg, basta usar o filtro de audio "volume":

$ ffmpeg -i input.wav -af 'volume=0.5' output.wav 

Nesse caso, o volume é diminuido pela metade.

Cortar vídeo usando FFmpeg

Exemplo: cortar um vídeo dos 2m10s aos 3m30s (1m20s a partir de 2m10s).

$ ffmpeg -ss 00:02:10 -i video.mp4 -to 00:01:20 -c copy cut.mp4

quarta-feira, 10 de setembro de 2014

Dividir tela do vídeo usando FFMPEG | Split Screen Using FFMPEG

Exemplo 1: Colocar dois vídeos lado a lado.

Assuma que temos 2 vídeos, "a.mp4" e "b.mp4", com a mesma resolução 720x480 pixels. E desejamos colocá-los lado a lado em um único vídeo "out.mp4" de 720x480 pixels. Pode-se usar o seguinte comando:
 $ ffmpeg -i a.mp4 -vf "scale=360:480 [inScale]; \
   color=c=black@1.0:s=720x480:r=29.75:d=9.0 [bg];\
   movie=b.mp4, scale=360:480 [vid2]; \
   [bg] [vid2] overlay=360:0 [basis1]; \
   [basis1] [inScale] overlay=0:0" out.mp4

A expressão entre parênteses é a descrição do filtro (filtergraph). A partir dessa expressão é possível montar um diagrama de blocos, para entendermos melhor como ele funciona.


O vídeo "a.mp4" é reescalado para metade da largura (causará distorção) e o resultado fica no nó [inScale]. No nó [bg], é criado um fundo preto de tamanho 720x480, com taxa de frame de 29.75 e duração de 9 segundos. No nó [vid2], é introduzido o vídeo "b.mp4" e reescalado. Agora o nó [vid2] é sobreposto ao nó [bg] na posição 360:0. O resultado está no nó [basis1], onde o nó [inScale] será sobreposto na posição 0:0. E o resultado será salvo no arquivo "out.mp4".

Exemplo 2: Colocar um vídeo em cima do outro .

Da mesma forma que o exemplo 1, porém com algumas modificações.

 $ ffmpeg -i a.mp4 -vf "scale=720:240 [inScale]; \
   color=c=black@1.0:s=720x480:r=29.75:d=9.0 [bg];\
   movie=b.mp4, scale=720:240 [vid2]; \
   [bg] [vid2] overlay=0:240 [basis1]; \
   [basis1] [inScale] overlay=0:0" out.mp4

A diferença está ao reescalar os vídeos "a.mp4" e "b.mp4", e na posição de sopreposição do segundo vídeo.

Exemplo 3: Dividir a tela para quatro vídeos.

Agora assuma que temos 4 vídeos, "a.mp4", "b.mp4", "c.mp4" e "d.mp4", com a mesma resolução 720x480 pixels. E desejamos colocá-los em duas linhas e duas colunas em um único vídeo "out.mp4" de 720x480 pixels. Pode-se usar o seguinte comando:

 $ ffmpeg -i a.mp4  -vf "scale=360:240 [inScale]; \
   color=c=black@1.0:s=720x480:r=29.75:d=9.0 [bg];\
   movie=b.mp4, scale=360:240 [vid2]; \
   movie=c.mp4, scale=360:240 [vid3]; \
   movie=d.mp4, scale=360:240 [vid4]; \
   [bg] [vid2] overlay=360:0 [basis1]; \
   [basis1] [vid3] overlay=0:240 [basis2]; \
   [basis2] [vid4] overlay=360:240 [basis3]; \
   [basis3] [inScale] overlay=0:0" out.mp4

O princípio é o mesmo dos exemplos anteriores, só que desta vez com mais dois blocos de sobreposição. Neste exemplo não ocorre distorção nas imagens (mantem a proporção do aspecto). A seguir tem o vídeo resultante do exemplo 3:


Como pode-se observar, existe uma infinidade de variações que pode ser feita com esses filtros do ffmpeg, basta usar a imaginação. ;) Espero ter ajudado.


Fontes:




sexta-feira, 22 de agosto de 2014

GVIM como IDE para Python e C/C++

Olá!
Procurando na internet, encontrei alguns scripts para Vim que me ajudaram a usar o GVIM como um ambiente de desenvolvimento para Python e C/C++.
Segue a lista deles:

Estou disponibilizando o arquivo ".vimrc" e a pasta ".vim/" que utilizo.

Fiz um vídeo que mostra como ficou.



O plugin pra C/C++ é muito bom, já para Python deixa a desejar. Tive que juntar um script daqui, outro dali para tentar utilizar como IDE para Python. De fato, GVIM não é uma IDE. Apesar do GVIM ser bastante customizável, é difícil encontrar para Python um projeto tão legal como o c.vim. Buscando mais um pouco, encontrei uma IDE (de fato!) para Python. Se chama PyCharm, e é muito boa. E ainda tem um plugin chamado ideavim, que é plugin de emulação do Vim.

Bom, é isso aí! Quem tiver mais ideias, opiniões, é só deixar nos comentários. Valeu!

Python + Numpy + C

Nesse post, vou mostrar um exemplo que fiz de como usar as UFuncs do Numpy. Me baseei neste link (Escrevendo sua própria ufunc) para fazer esse código.
No exemplo, eu criei duas funções em C para usar no Python. Segue o código do arquivo "minhasufuncs.c".

 #include "Python.h"  
 #include "math.h"  
 #include "numpy/ndarraytypes.h"  
 #include "numpy/ufuncobject.h"  

 // Estrutura usada para descrever um método de um tipo de extensão.  
 static PyMethodDef MinhasufuncsMethods[] = {  
     {NULL, NULL, 0, NULL}  
 };  
 //Função 1  
 static void double_FtoERB(char **args, npy_intp *dimensions,  
               npy_intp* steps, void* data)  
 {  
   npy_intp i;  
   npy_intp n = dimensions[0];  
   char *in = args[0], *out = args[1];  
   npy_intp in_step = steps[0], out_step = steps[1];  
   for (i = 0; i < n; i++) {  
     *((double *)out) = 24.7 * (4.37 * 1E-3 * (*(double *)in) + 1.);  
     in += in_step;  
     out += out_step;  
   }  
 }  
 // Função 2  
 static void double_sinc(char **args, npy_intp *dimensions,  
               npy_intp* steps, void* data)  
 {  
   npy_intp i;  
   npy_intp n = dimensions[0];  
   char *in = args[0], *out = args[1];  
   npy_intp in_step = steps[0], out_step = steps[1];  
   for (i = 0; i < n; i++) {  
     *((double *)out) = sin((*(double *)in)) / (*(double *)in) ;  
     in += in_step;  
     out += out_step;  
   }  
 }  
 // Estes são ponteiros para as funções acima  
 PyUFuncGenericFunction FtoERBfuncs[1] =   {&double_FtoERB};  
 PyUFuncGenericFunction sincfuncs[1] =   {&double_sinc};  
 // Estes são as entradas e retorna os dtypes  
 static char FtoERBtypes[2] = {NPY_DOUBLE, NPY_DOUBLE};  
 static char sinctypes[2] = {NPY_DOUBLE, NPY_DOUBLE};  
 static void *FtoERBdata[1] = {NULL};  
 static void *sincdata[1] = {NULL};  
 // Inicializa o módulo "minhasufuncs"  
 PyMODINIT_FUNC initminhasufuncs(void)  
 {  
   PyObject *m, *FtoERB, *sinc, *d;  
   m = Py_InitModule("minhasufuncs", MinhasufuncsMethods);  
   if (m == NULL) {  
     return;  
   }  
   import_array();  
   import_umath();  
   FtoERB = PyUFunc_FromFuncAndData(FtoERBfuncs, FtoERBdata, FtoERBtypes, 1, 1, 1,  
                   PyUFunc_None, "FtoERB",  
                   "FtoERB_docstring", 0);  
   sinc = PyUFunc_FromFuncAndData(sincfuncs, sincdata, sinctypes, 1, 1, 1,  
                   PyUFunc_None, "sinc",  
                   "sinc_docstring", 0);  
   d = PyModule_GetDict(m);  
   PyDict_SetItemString(d, "FtoERB", FtoERB);  
   Py_DECREF(FtoERB);  
   PyDict_SetItemString(d, "sinc", sinc);  
   Py_DECREF(sinc);  
 }  

São criadas duas funções para ser usadas no Python: "FtoERB" e "sinc". Tais funções serão chamadas a partir de um módulo a ser importado no Python, nesse caso, chamado "minhasufuncs". Para gerar a biblioteca compartilhada, usei um arquivo "setup.py". Segue:

 def configuration(parent_package='', top_path=None):  
   import numpy  
   from numpy.distutils.misc_util import Configuration  
   config = Configuration('',  
               parent_package,  
               top_path)  
   config.add_extension('minhasufuncs', ['minhasufuncs.c'])  
   return config  
 if __name__ == "__main__":  
   from numpy.distutils.core import setup  
   setup(configuration=configuration)  

E rode o comando:
 $ python setup.py build_ext --inplace   

Com isso, será gerado um arquivo "minhasufuncs.so". É só chama-lo no Python. Então segue um código-exemplo que chama essas funções.

 # -*- coding: utf-8 -*-  
 #/usr/bin/python  
   
 import numpy as np  
 import minhasufuncs  
 import matplotlib.pyplot as mpl  
   
 x1 = np.linspace(-30,30,8000)  
 y1 = minhasufuncs.sinc(x1)  
 x2 = np.linspace(0,8000,8000)  
 y2 = minhasufuncs.FtoERB(x2)  
 mpl.figure(figsize=(7,12))  
 mpl.subplot(211)  
 mpl.plot(x1,y1,'k',lw=2)  
 mpl.grid()  
 mpl.subplot(212)  
 mpl.plot(x2,y2,'k',lw=2)  
 mpl.grid()  
 mpl.savefig('minhasufuncs.png')  

Os gráficos gerados foram:

CLIQUE AQUI para baixar os meus arquivos.

É isso aí!