设为首页 收藏本站
查看: 661|回复: 0

[经验分享] 使用C语言扩展Python(三)

[复制链接]

尚未签到

发表于 2015-4-23 08:15:48 | 显示全部楼层 |阅读模式
上一篇中我们已经了解如何在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:

DSC0000.gif DSC0001.gif 代码

#include
#include
#include
#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);
        status = -1;
        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
#include
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,打开听听看是否是你想要的歌曲呢,呵呵。。。
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59804-1-1.html 上篇帖子: Python之lxml库学习笔记一 下篇帖子: 使用C语言扩展Python(二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表