上一篇中我们已经了解如何在Python程序和C模块之间进行值的相互传递,现在我们来进入实作阶段,看看如何将一个C语言开发的开源mp3编解码库LAME包装为一个Python下可以使用的扩展模块。

首先去http://lame.sourceforge.net/download.php下载LAME的源代码,然后切换到root用户编译源代码,

./configure

make

make install

安装完成后你可以在/usr/local/include/lame目录下找到lame.h头文件,我们在后面的demo程序中会include它的,下面就是一个非常简单的lame示例程序lame_test.c:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png代码

#include#include#include#defineINBUFSIZE 4096#defineMP3BUFSIZE (int) (1.25 * INBUFSIZE) + 7200intencode(char*inPath,char*outPath) {intstatus=0;

lame_global_flags*gfp;intret_code;

FILE*infp;

FILE*outfp;short*input_buffer;intinput_samples;char*mp3_buffer;intmp3_bytes;

gfp=lame_init();if(gfp==NULL) {

printf("lame_init failed\n");

status=-1;gotoexit;

}

ret_code=lame_init_params(gfp);if(ret_code<0) {

printf("lame_init_params returned %d\n",ret_code);

status=-1;gotoclose_lame;

}

infp=fopen(inPath,"rb");

outfp=fopen(outPath,"wb");

input_buffer=(short*)malloc(INBUFSIZE*2);

mp3_buffer=(char*)malloc(MP3BUFSIZE);do{

input_samples=fread(input_buffer,2, INBUFSIZE, infp);

mp3_bytes=lame_encode_buffer_interleaved(gfp, input_buffer,input_samples/2, mp3_buffer, MP3BUFSIZE);if(mp3_bytes<0) {

printf("lame_encode_buffer_interleaved returned %d\n", mp3_bytes);

status=-1;gotofree_buffers;

}elseif(mp3_bytes>0) {

fwrite(mp3_buffer,1, mp3_bytes, outfp);

}

}while(input_samples==INBUFSIZE);

mp3_bytes=lame_encode_flush(gfp, mp3_buffer,sizeof(mp3_buffer));if(mp3_bytes>0) {

printf("writing %d mp3 bytes\n", mp3_bytes);

fwrite(mp3_buffer,1, mp3_bytes, outfp);

}

free_buffers:

free(mp3_buffer);

free(input_buffer);

fclose(outfp);

fclose(infp);

close_lame:

lame_close(gfp);

exit:returnstatus;

}intmain(intargc,char**argv) {if(argc<3) {

printf("usage: lame_test rawinfile mp3outfile\n");

}

encode(argv[1], argv[2]);return0;

}

编译步骤:

gcc -I/usr/local/include/lame lame_test.c -lmp3lame -o lame_test

试验准备:

首先需要一个test.wav文件,先安装sox来将wav文件转为raw格式的数据:

sudo apt-get install sox

sox test.wav -t raw test.raw

然后执行lame_test来对其进行mp3编码:

./lame_test./test.raw./test.mp3

好了,现在我们要在这个c程序的基础上将其包装为一个Python扩展模块。下面的pylame.c就是简单地调用lame_test.c中定义的encode方法,然后通过它对外部的python程序提高mp3编码的服务

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png代码

#include#includeintencode(char*,char*);staticPyObject*pylame_encode(PyObject*self, PyObject*args) {intstatus;char*inPath;char*outPath;if(!PyArg_ParseTuple(args,"ss",&inPath,&outPath)) {returnNULL;}status=encode(inPath, outPath);returnPy_BuildValue("i", status);}staticPyMethodDef pylame_methods[]={{"encode", pylame_encode, METH_VARARGS, NULL},{NULL, NULL,0, NULL}};PyMODINIT_FUNC initpylame() {Py_InitModule3("pylame", pylame_methods,"an simple lame module.");}

模块编译步骤:

gcc -shared -I/usr/include/python2.6-I/usr/local/include/lame/pylame.c lame_test.c -lmp3lame -o pylame.so

ok,现在lame扩展模块已经封装好了,可以到python程序中进行调用了。在pylame.so所在目录下新建一个python文件lame1.py代码如下:

importpylameif__name__=='__main__':inPath='./test.raw'outPath='./test.mp3'pylame.encode(inPath, outPath)

编译执行:

python./lame1.py

你会发现生成了一个test.mp3,打开听听看是否是你想要的歌曲呢,呵呵。。。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐