Linux中国  设为主页
 收藏本站
 
当前位置: > 首页 ->Linux技术 ->Linux程序设计 ->基于libmad 的简单MP3流媒体播放器的实现
  相关分类: 
入门与提高
系统管理
网络应用
嵌入式系统
内核研究
服务器相关
发行版专区
Linux程序设计
Linux安全
BSD相关
桌面应用
  站内搜索: 
热门文章排行
热门文章排行 Linux系统下C语言编程 基础知识介绍 (05-01)
快速编辑Shell命令行(06-04)
Linux系统环境下的Socket编程详细解(04-19)
Awk 实例(一) (04-22)
基于libmad 的简单MP3流媒体播放器的(04-22)
精采文章排行
精采文章排行 快速编辑Shell命令行(06-04)
从2.4到2.6内核发展中的改进(06-04)
两个很详细的shell实例(06-04)
内核设计篇(06-04)
shell技巧(06-04)
 

基于libmad 的简单MP3流媒体播放器的实现

作者:李 素科    来源:linux.chinaunix.net   点击:   日期:2007-04-22 [收藏] [投稿]

  IE是否经常中毒?推荐您

ret_val =  pthread_create(&thread[0],
                            NULL,
                            get_http_content, 
                            &read_val);
  if (ret_val != 0) {
     printf("Cannot create get_http_content thread!\n");
     return 1;
  } 
  ret_val =  pthread_create(&thread[1],
                            NULL,
                            play_http_content, 
                            &read_val);
  if (ret_val != 0) {
     printf("Cannot create play_http_content thread!\n");
     return 1;
  }

  pthread_join(thread[0], NULL);
  pthread_join(thread[1], NULL);

可以看到,数据接收线程的线程主函数是 get_http_content, 而播放音乐的线程主函数是 play_http_content。创建子线程后,主线程调用 pthread_join() 等待子结束,并释放线程相关资源。

5.接收 MP3 流媒体数据

由于 MP3 流媒体数据是在 HTTP 服务器的文件目录中,所以,必须由客户端发送 HTTP 请求,然后得到相关 URL 的 HTTP 响应。HTTP 的请求格式如下:

<Method>  <Request-URI>  <HTTP-1.x> CRLF 
 *(( general-header        
   | request-header         
   | entity-header ) CRLF)
CRLF
 [ message-body ]

这里 CR(13) 表示回车,LF 表示换行。

根据 HTTP 请求格式,可以构建发送到 HTTP 服务器请求。比如,想要往 192.168.0.123 HTTP 发送获得文件 http://192.168.0.123/45.MP3 那么构建的请求是:

GET    /45.MP3   HTTP/1.1\r\n
HOST: 192.168.0.123\r\n\r\n

发送请求后,HTTP 服务器会就请求做出响应。如果请求合法,那么响应包括响应的媒体信息,包括 HTTP/1.1 200 OK,表示请求成功。最简单验证请求是否有效的方法是使用 telnet。 例如:

[root@localhost netmad]# telnet 192.168.0.123   80
Trying 192.168.0.123...
Connected to 192.168.0.123(192.168.0.123).
Escape character is '^]'.
HEAD /45.MP3 HTTP/1.1
HOST:192.168.0.123

HTTP/1.1 200 OK
Date: Tue, 14 Nov 2006 10:11:43 GMT
Server: Apache/2.2.0 (Fedora)
Last-Modified: Tue, 17 Oct 2006 15:08:16 GMT
ETag: "3147c9-32e080-1fb83800"
Accept-Ranges: bytes
Content-Length: 3334272
Connection: close
Content-Type: audio/mpeg
X-Pad: avoid browser bug

这里可以看到在 HTTP 请求的响应中,有关于 45.MP3 的简单信息,包括文件类型 Content-Type: audio/mpeg,以及文件的长度 Content-Length: 3334272。通过解析 HTTP 响应,很容易从 Content-Length 项得到 MP3 数据总的长度。为了发送 HTTP 请求,首先从播放器程序传递的参数解析出请求的资源的 URI,比如程序传递参数为 http://192.168.0.123/45.MP3 那么解析此 URL,得到 HTTP 请求的资源 URI 是 /45.MP3get_address 函数简单地解析了 URL,用 gethostbyname( ) 获得域名以及操作 socket 需要的地址信息。本文用于网络通信的一些 socket 相关的函数如下:

#include <sys/types.h>
#include <sys/socket.h>

int socket (int family, int type, int protocol)

此函数创建 socket 。

int  connect(int  sockfd,  const  struct sockaddr *serv_addr, socklen_t addrlen);

和目标地址服务程序连接,完成 3 次握手。

int recv(int s, void *buf, size_t len, int flags);

此函数从创建的 socket 接收数据。

6.数据接收线程和音乐播放线程

由于是两个线程并发运行,且音乐播放线程线程运行速度较慢。如果网络速度较快,数据接收线程的接收缓冲区满后,如果当前音乐播放线程正在播放音乐,那么数据接收线程必须停止接收数据。如果不让数据接收线程进入等待状态,它会一直轮训音乐播放线程观察其是否需要数据,简单的轮询会浪费 CPU 资源,所以在这种情况下,有必要让数据接收线程进入等待状态。本文使用信号量机制,来动态控制线程的运行。数据接收缓冲区必须留出一定的空间,存放解码缓冲区中没有被解码的数据。那么要留出多少数据空间呢?至少应该留出一帧数据的空间。这里 8192 字节空间存放剩余的一帧 MPEG 数据,一般情况下应该够用。因此定义:

·从2.4到2.6内核发展中的改进·两个很详细的shell实例·内核设计篇·shell技巧·批量添加用户·HowtoCreatingandBootingaNewKernelWitha·利用ip_conntrack表实现封ip的shell脚本,·30分钟搞定BASH脚本编程!·Shell初学者的入门知识
#define DECODE_BUF_SIZE   (8192*11)
#define GARD_SIZE         (8192*10)
static char decode_buf[DECODE_BUF_SIZE];
static char recv_buf[DECODE_BUF_SIZE];


 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<

上一页 1 2 3 4 56 下一页

上一篇:Java 2007:新年展望   下一篇:UNIX 目标文件初探
文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论

   相关文章:
·快速编辑Shell命令行

   文章评论:(1条)
  
 请留名: 匿名评论   点击查看所有评论 论坛讨论
 

 声明:刊登此文章是为了传递更多信息,文章内容仅供参考,转载请注明出处。