TonyChyi

我在那一角落患过抽风

基于libxmmsclient的Go语言绑定
2016年01月14日
 

 

代码:[email protected]

文档:[email protected]

在我发现 XMMS2 是使用了 C/S 架构以后,就有了一个想法:

用 Go/QML/XMMS2 写一个简单的音乐播放器,顺带可以收听网易云音乐

XMMS2 有很多种前端,从桌面到 Web 页面什么都有,然而大部分项目长期不更新了。

XMMS2 官方支持的语言有:C/C++/Python/Perl/Ruby。嗯,没有 Go

从上个周末开始,我尝试用抓包的方法来分析 XMMS2 的通讯协议,一无所获。

代码就很复杂了,还是二进制的协议,这怎么搞嘛!

不要重复造轮子!不要重复造轮子!不要重复造轮子! 重要的事情说三遍

显然更讨巧的办法是做一个绑定。

一开始我就有了下面这一套代码

package xmms2go

/*
#cgo CFLAGS: -I/usr/include/xmms2
#cgo LDFLAGS: -lxmmsclient
#include <xmmsclient/xmmsclient.h>
*/
import "C"
import (
    "errors"
    "fmt"
)

type Xmms2Client struct {
    Connection *X.xmmsc_connection_t
    result *C.xmmsc_result.t
    returnValue *C.xmmsv_t
    errorBuff *C.char
}

func NewXmms2Client(clientName string) (*Xmms2Client, error) {
    x := new(Xmms2Client)
    x.connection = C.xmmsc_init(C.CString(clientName))
    if x.Connection == nil {
        return nil, errors.New("Client init failed")
    }
    return x, nil
}

// 连接到 xmms2d
func (x *Xmms2Client) Connect(url string) error {
    r := C.xmmsc_connect(x.Connection, C.CString(url))
    if interface{}(r) == nil {
        errInfo := C.GoString(C.xmmsc_get_last_error(x.Connection))
        return errors.New(fmt.Sprintf("Connection failed: %s", errInfo))
    }
    return nil
}

// 发送播放指令
func (x *Xmms2Client) Play() error {
    x.result = C.xmmsc_playback_start(x.Connection)
    C.xmmsc_result_wait(x.result)
    x.returnValue = C.xmmsc_result_get_value(x.result)
    if int(C.xmmsv_is_error(x.returnValue)) != 0 &&
        int(C.xmmsv_get_error(x.returnValue, &x.errorbuff)) != 0 {
        errInfo := C.GoString(x.errorBuff)
        return errors.New(fmt.Sprintf(
            "Playback start returned error: %s", errInfo)
        )
    }
    return nil
}

// XMMS2 的文档说要unref,不然就麻烦了
func (x *Xmms2Client) Unref() {
    C.xmmsc_result_unref(x.result)
    C.xmmsc_unref(x.Connection)
}

好吧,其实这是一段相当丑陋的代码,然后我使用 Go 的 testing 包进行单元测试的时候,嗯,它完全能工作。(事实上这一部分代码到现在还是没有优化)

到今天为止,xmmsv_t 的基本类型我已经封装完成,xmmsv_list_t 封装了一部分,迭代器还没有封装。 有关 Xmms2Client 的部分,等到以后有时间还得重做。也希望能有个人加入进来,一起做这个东西。(我 C 语言的水平还是太一般)

Tags: #Go · #Xmms2 · #C

 

TonyChyi © 2020 GPLv2