上一篇中我們已經了解如何在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:
複制代碼
代碼
#include <stdio.h>
#include <stdlib.h>
#include <lame.h>
#define INBUFSIZE 4096
#define MP3BUFSIZE (int) (1.25 * INBUFSIZE) + 7200
int encode(char* inPath, char* outPath) {
int status = 0;
lame_global_flags* gfp;
int ret_code;
FILE* infp;
FILE* outfp;
short* input_buffer;
int input_samples;
char* mp3_buffer;
int mp3_bytes;
gfp = lame_init();
if (gfp == NULL) {
printf("lame_init failed\n");
status = -1;
goto exit;
}
ret_code = lame_init_params(gfp);
if (ret_code < 0) {
printf("lame_init_params returned %d\n",ret_code);
goto close_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;
goto free_buffers;
} else if(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:
return status;
}
int main(int argc, char** argv) {
if (argc < 3) {
printf("usage: lame_test rawinfile mp3outfile\n");
encode(argv[1], argv[2]);
return 0;
編譯步驟:
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編碼的服務
#include <Python.h>
int encode(char* ,char*);
static PyObject * pylame_encode(PyObject* self, PyObject* args) {
int status;
char* inPath;
char* outPath;
if (!PyArg_ParseTuple(args, "ss", &inPath, &outPath)) {
return NULL;
status = encode(inPath, outPath);
return Py_BuildValue("i", status);
static PyMethodDef 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代碼如下:
import pylame
if __name__ == '__main__':
inPath = './test.raw'
outPath = './test.mp3'
pylame.encode(inPath, outPath)
編譯執行:
python ./lame1.py
你會發現生成了一個test.mp3,打開聽聽看是否是你想要的歌曲呢,呵呵。。。
本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2010/05/22/1741667.html,如需轉載請自行聯系原作者