让linux支持qq手机音乐播放

Gmediarender 是一个仿真upnp renderlinux下的软件,他可以接收qq音乐发来的数据并在电脑上播放出来。下面介绍一下方法:

网站http://gmrender.nongnu.org/下载gmediarender

  编译,编译过程回出现

gcc  -Wall -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -L/usr/lib  -o gmediarender  main.o upnp.o upnp_control.o upnp_connmgr.o upnp_transport.o upnp_device.o upnp_renderer.o webserver.o output_gstreamer.o xmlescape.o -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lxml2 -lglib-2.0   -lupnp 
/usr/bin/ld: upnp.o: undefined reference to symbol 'ixmlDocument_createElementNS'
//usr/lib/x86_64-linux-gnu/libixml.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
这样的错误,grep上面的函数发现在下面文件里面:
/usr/lib/x86_64-linux-gnu/libixml.a
/usr/lib/x86_64-linux-gnu/libixml.so.2.0.7
解决方法,直接链接静态库:
gcc  -Wall -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -L/usr/lib  -o gmediarender  main.o upnp.o upnp_control.o upnp_connmgr.o upnp_transport.o upnp_device.o upnp_renderer.o webserver.o output_gstreamer.o xmlescape.o -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lxml2 -lglib-2.0   -lupnp  /usr/lib/x86_64-linux-gnu/libixml.a
安装完成后即可用手机qq音乐连接测试。

首先要保证电脑和手机连接到同一个网段(同一个wifi ap),在pc端运行gmediarender,然后打开qq音乐后开始播放音乐,在播放界面出现一个圈圈带箭头图标,点击该图标显示出新的播放设备gmediarender,点击后音乐就发送到了pc上,pc电脑就可以出声音了。

Gmediarender 仅支持gst,我对其做了mpd的简单扩展,让声音可以从mpd里面播放出来,下面是扩展mpd支持的代码(非常初级,仅仅可以让mpd播放声音而已):

output_mpd.c

#ifdef HAVE_CONFIG_H

#include "config.h"

#endif

#include <mpd/client.h>

#include <mpd/status.h>

#include <mpd/song.h>

#include <mpd/entity.h>

#include <mpd/search.h>

#include <mpd/tag.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <glib.h>

//#define ENABLE_TRACING

#include "logging.h"

#include "upnp_connmgr.h"

#include "output_mpd.h"

static char *gsuri = NULL;

static struct mpd_connection *conn = NULL;

#define SET_CONN() conn = mpd_connection_new(NULL, 0, 30000)

#define FREE_CONN() mpd_connection_free(conn); conn=NULL

struct mpd_status *

getStatus(struct mpd_connection *conn)

{

struct mpd_status *ret = mpd_run_status(conn);

return ret;

}

static unsigned

query_queue_length(struct mpd_connection *conn)

{

struct mpd_status *status = getStatus(conn);

const unsigned length = mpd_status_get_queue_length(status);

mpd_status_free(status);

return length;

}

void output_set_uri(const char *uri)

{

ENTER();

printf("%s: setting uri to '%s'\n", __FUNCTION__, uri);

if (gsuri != NULL)

{

free(gsuri);

}

gsuri = strdup(uri);

LEAVE();

}

int output_play(void)

{

int result = -1;

int try_num=10;

enum mpd_server_error serror_error;

ENTER();

if(strlen(gsuri)==0)

{printf("usri is empty:%s\n");return -1;};

SET_CONN();

//next schedule it to the next play

printf("conn=%x\n",(unsigned int )conn);

struct mpd_status *status = getStatus(conn);

if(status==NULL)

{

if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {

printf("connection error code:%d,free connection\n", mpd_connection_get_error(conn));

serror_error=mpd_connection_get_server_error(conn);

printf("serror=%d\n",serror_error);

mpd_connection_free(conn);

}

}

const int playlist_len=mpd_status_get_queue_length(status);

printf("---playlist_len=%d,add song:%s\n",playlist_len,gsuri);

mpd_command_list_begin(conn, false);

if(playlist_len)

{

const int next_song_pos=mpd_status_get_next_song_pos(status);

printf("next_song_pos=%d\n",next_song_pos);

if(next_song_pos==-1)

{

mpd_send_add(conn,gsuri);

}

else

mpd_send_add_id_to(conn, gsuri,next_song_pos);

}

else{

mpd_send_add(conn,gsuri);

}

mpd_command_list_end(conn);

mpd_response_finish(conn);

mpd_run_play(conn); 

if(playlist_len)

mpd_run_next(conn);

   mpd_status_free(status);

   FREE_CONN();

result = 0;

LEAVE();

return result;

}

int output_stop(void)

{

SET_CONN();

mpd_run_stop(conn);

FREE_CONN();

return 0;

}

int output_pause(void)

{

SET_CONN();

mpd_run_pause(conn,true);

FREE_CONN();

  return 0;

}

int output_loop()

{

GMainLoop *loop;

/* Create a main loop that runs the default GLib main context */

loop = g_main_loop_new(NULL, FALSE);

g_main_loop_run(loop);

return 0;

}

int output_mpt_init(void)

{

ENTER();

SET_CONN();

if (conn == NULL) {

printf("%s", "Out of memory");

return -1;

}

 

if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {

printf("%s", mpd_connection_get_error_message(conn));

mpd_connection_free(conn);

conn = NULL;

return -1;

}

FREE_CONN();

LEAVE();

return 0;

}

output_mpd.h

#ifndef _OUTPUT_MPD_H

#define _OUTPUT_GSTREAMER_H

int output_mpd_init(void);

void output_set_uri(const char *uri);

int output_play(void);

int output_stop(void);

int output_pause(void);

int output_loop(void);

#endif /*  _OUTPUT_MPD_H */

 

需要注意的是qq网络音乐是把mov的后缀改动为后缀为mqcc的形式(qq本地传入的音乐),而mpd又是以后缀作为解码的依据,这个可以修改文件src/decoder/plugins/FfmpegDecoderPlugin.cxx,找到:ffmpeg_suffixes,增加:"wve", "mqcc",后重新编译即可支持。

 

你可能感兴趣的:(linux,支持qq音乐)