当前位置:文档之家› 流媒体MP3播放器教程

流媒体MP3播放器教程

流媒体MP3播放器教程
流媒体MP3播放器教程

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

本文在Fedora 5 Linux 下实现了一个基于libmad 的mp3 流媒体播放器。此流媒体播放器可以播放基于HTTP 1.1 协议传输的MP3 流媒体数据。

基本原理是:从HTTP 服务器获得MP3 媒体信息,然后通过网络传输把MP3 数据以数据流的形式接收到MP3 流媒体播放器客户端,由客户端通过libmad 解码MP3 数据流,得到PCM 音频数据,写入音频设备,播放音乐。本文的流媒体播放器只是实现了必要的简单功能,没有考虑太多情况。比如,没有考虑实时播放控制,这样的话就不能随意选取播放点进行播放。

本文的MP3 流媒体播放器创建两个线程,使用两个缓冲区保存MP3 数据,可以一边下载数据,一边播放音乐。编译运行此MP3 流媒体播放器需要安装libmad

(https://www.doczj.com/doc/969572137.html,/prodUCts/mad/) 以及ALSA(Advanced Linux Sound Architecture)

(https://www.doczj.com/doc/969572137.html,)相关的软件。ALSA包括4部分,分别是sound driver, sound library , sound utilities 以及tools。至少应该安装sound driver, sound library 。编译程序时连接库的选项是:-lmad -lasound -lpthread。

本文的MP3 流媒体播放器使用双缓冲区,一个是数据接收缓冲区,另一个是数据解码缓冲区。主程序结构如下图所示,图中的蓝色线表示数据流向。

图1:MP3 流媒体播放器主程序结构图

2.libmad简介

MAD (libmad)是一个开源的高精度MPEG 音频解码库,支持MPEG-1(Layer I, Layer II 和LayerIII(也就是MP3)。LIBMAD 提供24-bit 的PCM 输出,完全是定点计算,非常适合没有浮点支持的平台上使用。使用libmad 提供的一系列API,就可以非常简单地实现MP3 数据解码工作。在libmad 的源代码文件目录下的mad.h 文件中,可以看到绝大部分该库的数据结构和API 等。

本文用到的libmad 中的主要数据结构有:struct mad_stream, struct mad_synth, struct mad_frame。它们的定义如下:

清单1:libmad 中的主要数据结构

struct mad_stream {

unsigned char const *buffer; /* input bitstream buffer */ unsigned char const *bufend; /* end of buffer */

unsigned long skiplen; /* bytes to skip before next frame */

int sync; /* stream sync found */

unsigned long freerate; /* free bitrate (fixed) */ unsigned char const *this_frame; /* start of current frame */ unsigned char const *next_frame; /* start of next frame */ struct mad_bitptr ptr; /* current processing bit pointer */

struct mad_bitptr anc_ptr; /* ancillary bits pointer */ unsigned int anc_bitlen; /* number of ancillary bits */ unsigned char (*main_data)[MAD_BUFFER_MDLEN];

/* Layer III main_data() */

unsigned int md_len; /* bytes in main_data */

int options; /* decoding options (see below) */

enum mad_error error; /* error code (see above) */ };

更多内容请看流媒体播放器流媒体文件格式播放技巧专题,或

如果缓冲区最后一个MPEG 数据帧只有部分数据包括在缓冲区中,那么struct

mad_stream中的next_frame域指到不完整数据的开始地址。

?由于缓冲区的MPEG 数据帧不一定完整,所以不完整的MPEG 帧的数据必须拷贝到下一次解码操作的缓冲区中,进行再次解码。这里我们还看到bufend指向缓冲区数据的最后地址,也就是最后一字节的地址加 1 的位置。mad_stream.bufend –

mad_stream.next_frame就是剩余的未被解码的MPEG 帧的数据的字节数量(假设此帧在缓冲区中不完整)。mad_stream的error域用来记录操作mad_stream得到的错误代码。错误代码在mad.h 中有很详细的定义。

?清单2:错误代码在mad.h 中的详细定义

?struct mad_synth {

? mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */

? /* [ch][eo][peo][s][v] */

? unsigned int phase; /* current processing phase */

? struct mad_pcm pcm; /* PCM output */

?};

mad_synth中的关键域pcm保存解码和合成后得到的PCM 数据。

清单3:mad_synth 中的关键域

struct mad_pcm {

unsigned int samplerate; /* sampling frequency (Hz) */ unsigned short channels; /* number of channels */

unsigned short length; /* number of samples per channel */

mad_fixed_t samples[2][1152]; /* PCM output samples

[ch][sample] */

};

struct mad_pcm定义了音频的采样率、每个声道个数以及最后的PCM 采样数据。这些参数可用来初始化音频设备。

清单4:struct mad_pcm

struct mad_frame {

struct mad_header header; /* MPEG audio header */ int options; /* decoding options (from stream) */

mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */

mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */

};

mad_frame是记录MPEG 帧解码后的数据的数据结构,其中的mad_header尤其重要,其用来记录MPEG 帧的一些基本信息,比如MPEG 层数、声道模式、流比特率、采样比特率等等。声道模式包括单声道、双声道、联合立体混音声以及一般立体声。

清单5:mad_frame

enum mad_mode {

MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */

MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */

MAD_MODE_STEREO = 3 /* normal LR stereo */ };

struct mad_header {

enum mad_layer layer; /* audio layer (1, 2, or 3) */ enum mad_mode mode; /* channel mode */

int mode_extension; /* additional mode info */

enum mad_emphasis emphasis; /* de-emphasis to use */

unsigned long bitrate; /* stream bitrate (bps) */ unsigned int samplerate; /* sampling frequency (Hz) */ unsigned short crc_check; /* frame CRC accumulator */ unsigned short crc_target; /* final target CRC checksum */ int flags; /* flags */

int private_bits; /* private bits */

mad_timer_t duration; /* audio playing time of frame */

};

下面就本文使用的API 的功能做简单介绍。

在本文中用到的API 包括:

void mad_stream_init(struct mad_stream *)

void mad_synth_init(struct mad_synth *);

void mad_frame_init(struct mad_frame *);

以上3个API 初始化解码需要的数据结构。

void mad_stream_buffer(struct mad_stream *, unsigned char const *, unsigned long);

此函数把原始的未解码的MPEG 数据和mad_stream数据结构关联,以便使用

mad_frame_decode( )来解码MPEG 帧数据。

int mad_frame_decode(struct mad_frame *, struct mad_stream *);

把mad_stream中的MPEG 帧数据解码。

void mad_synth_frame(struct mad_synth *, struct mad_frame const *);

把解码后的音频数据合成PCM 采样。

void mad_stream_finish(struct mad_stream *);

void mad_frame_finish(struct mad_frame *);

mad_synth_finish(struct mad_synth);

以上 3 个API 在解码完毕后使用,释放libmad 占用的资源等。

更多内容请看流媒体播放器流媒体文件格式播放技巧专题,或

3.PCM 音频设备的操作

对音频设备的操作主要是初始化音频设备以及往音频设备发送PCM(Pulse Code Modulation)数据。为了方便,本文使用ALSA(Advanced Linux Sound Architecture)提供的库和驱动。在编译和运行本文中的MP3 流媒体播放器的时候,必须先安装ALSA 相关的文件。

本文用到的主要对PCM 设备操作的函数分为PCM 设备初始化的函数以及PCM 接口的一些操作函数。

PCM 硬件设备参数设置和初始化的函数有:

int snd_pcm_hw_params_malloc (snd_pcm_hw_params_t **ptr)

int snd_pcm_hw_params_any (snd_pcm_t *pcm, snd_pcm_hw_params_t *params)

void snd_pcm_hw_params_free (snd_pcm_hw_params_t *obj)

int snd_pcm_hw_params_set_Access ( snd_pcm_t *pcm,

snd_pcm_hw_params_t

*params,

snd_pcm_access_t _access) int snd_pcm_hw_params_set_format ( snd_pcm_t *pcm,

snd_pcm_hw_params_t

*params,

snd_pcm_format_t val)

int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm,

snd_pcm_hw_params_t

*params,

unsigned int val)

int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm,

snd_pcm_hw_params_t

*params,

unsigned int *val, int *dir)

?PCM 接口的操作函数:

?int snd_pcm_hw_params (snd_pcm_t *pcm, snd_pcm_hw_params_t *params)

?int snd_pcm_prepare (snd_pcm_t *pcm)

?int snd_pcm_open (snd_pcm_t **pcm, const char *name,

? snd_pcm_stream_t stream, int mode)

?int snd_pcm_close (snd_pcm_t *pcm)

?snd_pcm_sframes_t snd_pcm_writei (snd_pcm_t *pcm,

? const void *buffer, snd_pcm_uframes_t size)

这些函数用到了snd_pcm_hw_params_t结构,此结构包含用来播放PCM 数据流的硬件信息配置。在往音频设备(声卡)写入音频数据之前,必须设置访问类型、采样格式、采样率、

声道数等。

首先使用snd_pcm_open ()打开PCM 设备,在ALSA 中,PCM 设备都有名字与之对应。比如我们可以定义PCM 设备名字为char *pcm_name = "plughw:0,0"。最重要的PCM 设备接口是“plughw”以及“hw”接口。使用“plughw”接口,程序员不必过多关心硬件,而且如果设置的配置参数和实际硬件支持的参数不一致,ALSA 会自动转换数据。如果使用“hw”接口,我们就必须检测硬件是否支持设置的参数了。Plughw 后面的两个数字分别表示设备号和次设备(subdevice)号。

snd_pcm_hw_params_malloc( )在栈中分配snd_pcm_hw_params_t结构的空间,

然后使用snd_pcm_hw_params_any( )函数用声卡的全配置空间参数初始化已经分配的snd_pcm_hw_params_t结构。snd_pcm_hw_params_set_access ( )设置访问类型,常用访问类型的宏定义有:

SND_PCM_ACCESS_RW_INTERLEAVED

交错访问。在缓冲区的每个PCM 帧都包含所有设置的声道的连续的采样数据。比如声卡要播放采样长度是16-bit 的PCM 立体声数据,表示每个PCM 帧中有16-bit 的左声道数据,然后是16-bit 右声道数据。

SND_PCM_ACCESS_RW_NONINTERLEAVED

非交错访问。每个PCM 帧只是一个声道需要的数据,如果使用多个声道,那么第一帧是第一个声道的数据,第二帧是第二个声道的数据,依此类推。

函数snd_pcm_hw_params_set_format()设置数据格式,主要控制输入的音频数据的类型、无符号还是有符号、是little-endian还是bit-endian。比如对于16-bit 长度的采样数据可以设置为:

?SND_PCM_FORMAT_S16_LE 有符号16 bit Little Endian

?SND_PCM_FORMAT_S16_BE 有符号16 bit Big Endian

?SND_PCM_FORMAT_U16_LE 无符号16 bit Little Endian

?SND_PCM_FORMAT_U16_BE 无符号 16 bit Big Endian

?

比如对于32-bit 长度的采样数据可以设置为:

SND_PCM_FORMAT_S32_LE 有符号32 bit Little Endian

SND_PCM_FORMAT_S32_BE 有符号32 bit Big Endian

SND_PCM_FORMAT_U32_LE 无符号32 bit Little Endian

SND_PCM_FORMAT_U32_BE 无符号 32 bit Big Endian

函数snd_pcm_hw_params_set_channels()设置音频设备的声道,常见的就是单声道和立体声,如果是立体声,设置最后一个参数为2。

snd_pcm_hw_params_set_rate_near ()函数设置音频数据的最接近目标的采样率。

snd_pcm_hw_params( )从设备配置空间选择一个配置,让函数snd_pcm_prepare()准备好PCM 设备,以便写入PCM 数据。snd_pcm_writei()用来把交错的音频数据写入到音频设备。

初始化PCM 设备的例程如下:

清单6:初始化PCM 设备的例程

/* open a PCM device */

int open_device(struct mad_header const *header)

{

int err;

snd_pcm_hw_params_t *hw_params;

char *pcm_name = "plughw:0,0";

int rate = header->samplerate;

int channels = 2;

if (header->mode == 0) {

channels = 1;

} else {

channels = 2;

}

if ((err = snd_pcm_open (&playback_handle,

pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {

printf("cannot open audio device %s (%s)\n",

pcm_name,

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {

printf("cannot allocate hardware parameter structure

(%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {

printf("cannot initialize hardware parameter structure (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_access (playback_handle,

hw_params,

SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {

printf("cannot set access type (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_format (playback_handle,

hw_params, SND_PCM_FORMAT_S32_LE)) < 0) {

printf("cannot set sample format (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params, &rate, 0)) < 0) {

printf("cannot set sample rate (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, channels)) < 0) {

printf("cannot set channel count (%s)\n",

snd_strerror (err));

return -1;

}

if ((err = snd_pcm_hw_params (playback_handle,

hw_params)) < 0) {

printf("cannot set parameters (%s)\n",

snd_strerror (err));

return -1;

}

snd_pcm_hw_params_free (hw_params);

if ((err = snd_pcm_prepare (playback_handle)) < 0) {

printf("cannot prepare audio interface for use (%s)\n", snd_strerror (err));

return -1;

}

return 0;

}

这里配置的PCM 格式是SND_PCM_FORMAT_S32_LE,采样的格式是每个采样有32-bit 的数据,数据按照little-endian存放。如果通过mad_frame_decode()函数得到

PCM 数据后,要求每个采样数据只占16-bit,需要把数据进行MAD的定点类型到signed short类型进行转换。那么,PCM 数据如何写入声卡中呢?函数实现例程如下所示:

更多内容请看流媒体播放器流媒体文件格式播放技巧专题,或

清单7:PCM 数据写入声卡函数实现例程

while (nsamples--) {

/* nsamples 是采样的数目 */

signed int sample;

sample = pcm->samples[0][j];

*(OutputPtr++) = sample & 0xff;

*(OutputPtr++) = (sample >> 8);

*(OutputPtr++) = (sample >> 16);

*(OutputPtr++) = (sample >> 24);

if (nchannels == 2) {

sample = pcm->samples[1][j];

*(OutputPtr++) = sample & 0xff;

*(OutputPtr++) = sample >> 8;

*(OutputPtr++) = (sample >> 16);

*(OutputPtr++) = (sample >> 24);

}

j++;

}

if ((err = snd_pcm_writei (playback_handle, buf, samples)) < 0) {

err = xrun_recovery(playback_handle, err);

if (err < 0) {

printf("Write error: %s\n", snd_strerror(err));

return -1;

}

}

这里用到了https://www.doczj.com/doc/969572137.html,/ 关于ALSA 文档中的例子函数xrun_recovery( )。详细例子请参见https://www.doczj.com/doc/969572137.html,/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html。使用此函数的目的是避免出现由于网络原因,声卡不能及时得到音频数据而使得snd_pcm_writei() 不能正常连续工作。实际上在xrun_recovery( ) 中,又调用snd_pcm_prepare() 和snd_pcm_resume() 以

实现能“恢复错误”的功能。-EPIPE 错误表示应用程序没有及时把PCM 采样数据送入ASLA 库。

xrun_recovery() 函数如下所示:

?清单8:xrun_recovery() 函数

?int xrun_recovery(snd_pcm_t *handle, int err)

?{

? if (err == -EPIPE) { /* under-run */

? err = snd_pcm_prepare(handle);

? if (err < 0)

? printf("Can't recovery from underrun, prepare failed: %s\n", ? snd_strerror(err));

? return 0;

? } else if (err == -ESTRPIPE) {

? while ((err = snd_pcm_resume(handle)) == -EAGAIN)

? sleep(1); /* wait until the suspend flag is released */

? if (err < 0) {

? err = snd_pcm_prepare(handle);

? if (err < 0)

? printf("Can't recovery from suspend, prepare failed: %s\n",

? snd_strerror(err));

? }

? return 0;

? }

? return err;

?}

知道了具体的音频设备操作方法,就该使用MAD 提供的函数具体实现解码了。函数

mp3_decode_buf( )提供了使用libmad 解码的方法。首先调用

mad_stream_buffer()函数把MP3 流数据和decode_stream关联,然后开始循环解码数据。如果在解码数据过程中,有不完整PCM 数据帧,那么decode_stream.error 的值就是MAD_ERROR_BUFLEN,且decode_stream.next_frame不为NULL。这时

候,把剩余的未解码的数据再拷贝到数据解码缓冲区里。mad_frame_decode( )函数从decode_stream中得到PCM 数据。

清单9:mad_frame_decode( ) 函数从decode_stream 中得到PCM 数据

int mp3_decode_buf(char *input_buf, int size)

{

int decode_over_flag = 0;

int remain_bytes = 0;

int ret_val = 0;

mad_stream_buffer(&decode_stream, input_buf, size);

decode_stream.error = MAD_ERROR_NONE;

while (1)

{

if (decode_stream.error == MAD_ERROR_BUFLEN) {

if (decode_stream.next_frame != NULL) {

remain_bytes = decode_stream.bufend -

decode_stream.next_frame;

memcpy(input_buf, decode_stream.next_frame,

remain_bytes);

return remain_bytes;

}

}

ret_val = mad_frame_decode(&decode_frame, &decode_stream); /* 省略部分代码 */

...

if (ret_val == 0) {

if (play_frame(&decode_frame) == -1) {

return -1;

}

}

/* 后面代码省略 */

...

}

return 0;

}

4.创建线程

本文使用POSIX 线程库(pthreads)来创建线程。比如,本文需要两个线程,一个是数据接收线程,另一个是音乐播放线程。创建线程的程序如下所示:

清单10:创建线程

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 的请求格式如下:

CRLF

*(( general-header

request-header

entity-header ) CRLF)

CRLF

[ message-body ]

?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.MP3。get_address函数简单地解析了URL,用gethostbyname( )获得域名以及操作socket 需要的地址信息。本文用于网络通信的一些socket 相关的函数如下:

#include

#include

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 数据,一般情况下应该够用。因此定义:

#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];

GARD_SIZE是一次从socket 读取数据字节数的最大值,而解码缓冲区的大小应该是比GARD_SIZE大8192 字节,因此定义DECODE_BUF_SIZE为(8192*11)。recv_buf 是数据接收缓冲区,decode_buf是数据解码缓冲区。在拷贝数据到解码缓冲区的时候,上次未解码的数据,还被保存在解码缓冲区的开始部分,故拷贝数据的时候,必须拷贝到剩余数据的后面,程序例子如下:

memcpy(decode_buf + current_remain, recv_buf, current_read); current_read += current_remain;

这里的current_remain表示上次解码线程中未解码的不完整MP3 帧的数据字节数,current_read表示当前接收线程接收到的实际数据字节数。两个缓冲区之间的数据拷贝操作如下图所示。

图2:缓冲区之间的数据拷贝操作

数据接收线程和音乐播放线程之间的同步

由于使用了双缓冲区保存数据,所以,在音乐播放线程播放音乐的时候,数据接收线程不能把数据拷贝到数据解码缓冲区,而是需要等待。当数据接收缓冲区满的时候,接收线程自己也需要等待。本文用到了POSIX 信号量处理函数,实现了线程之间的同步。它们分别是:

?#include

?int sem_init(sem_t *sem, int pshared, unsigned int value);

?

初始化信号量,第三个参数表示初始的信号量的计数。

int sem_wait(sem_t * sem);

sem_wait阻塞当前线程的执行,直到信号量的计数非0;然后,它会把信号量计数减1,然后程序继续执行。相当于P 操作。

int sem_post(sem_t * sem);

把sem指向的信号量计数加1。相当于V 操作。

int sem_destroy(sem_t * sem);

释放信号量对象。

在程序中,信号量定义及初始化为:

static sem_t empty_sem;

static sem_t decode_sem;

static sem_t copy_sem;

sem_init(&empty_sem, 0, 1);

sem_init(&decode_sem, 0, 0);

sem_init(?_sem, 0, 1);

更多内容请看流媒体播放器流媒体文件格式播放技巧专题,或

empty_sem 信号量的计数表示接收缓冲是否为空,其中如果是 1,表示为空;如果为 0 表示不为空。decode_sem 信号量的计数表示音乐播放线程是否正在对数据解码缓冲区的数据进行解码,如果是 1 表示正在进行解码,如果是 0 表示没有解码;copy_sem 信号量的计数表示是否可以从

蓝牙车载音频流播放器的设计与实现

蓝牙车载音频流播放器的设计与实现 现在的车载信息娱乐系统中标准配置有带CD 播放功能的收音机、液晶屏,其他可选配置有GPS 和蓝牙免提装置等设备。随着蓝牙技术在音视频传输中的应用,一种可以增强用户娱乐体验的蓝牙音频流播放功能正逐步在车载信息娱 乐系统中得到应用。蓝牙音频流播放功能是指将蓝牙MP3 或蓝牙手机上的音 乐通过蓝牙以流媒体的方式传输到远端设备上进行解码后通过远端设备的功放 系统播放,同时远端设备还带有远程控制功能,使得用户可以在远端设备上操 作音乐,使其暂停、播放、快进快退或进行上下首切换。笔者设计实现了一款 蓝牙车载音频流播放器,该播放器和收音机及液晶屏之间通过CAN 总线进行 连接,控制操作在收音机上实现,液晶屏显示音乐的tagID3、播放时间、音轨、总音轨等信息,控制命令和播放信息都是通过CAN 总线进行传输。从用户的 使用角度来说,该蓝牙音频流播放器是和收音机、液晶屏组成一套系统的。1 系统结构系统结构如图1 所示。音频流播放器、液晶屏和收音机组成一个车载娱乐系统的CAN 网络,控制命令及状态信息均通过CAN 总线传输,其中收 音机带有功放,直接驱动汽车喇叭,并统一管理包括FM、CD 和音频流播放器的音频输出在内的音源。音频流播放器和蓝牙手机通过蓝牙进行交互,采用 A2DP(Advanced Audio Distribution Profile)完成音乐音频流数据及相关格式信息的传输,通过AVRCP(Audio/Video Remote Control Profile)完成对音乐的远程播放控制及播放信息及状态的读取。在A2DP 中引入了2 个终端名:SRC(Source) 和SNK(Sink)。在这里,数字音频流的数据发送端蓝牙手机称为SRC,数字音 频流的接收端蓝牙音频流播放器称为SNK。 2 硬件设计蓝牙音频流播放器的硬件设计中,包括CAN 通讯、蓝牙子系统和音频系统 3 个部分,其中蓝牙子系统和音频系统部分采用CSR 的蓝牙单芯片

音乐播放器的详细设计

音乐播放器详细设计 1.引言 随着社会的快速发展,现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,音乐成了我们生活工作中的一个重要的部分。而3G时代的到来,手机移动应用越来越普遍。此文档就是为了能更好地设计出一个基于android系统的音乐播放器而编写的。 1.1 编写目的 为软件的开发者能更好的理解和明确软件开发的详细过程,安排项目与进度、组织软件开发与测试,撰写本文档。本文档供项目组成员,软件开发人员参考。1.2项目背景 本项目由李雪梅、杨挺等人提出,由本组成员联合开发,实现播放现今流行的音乐MP3等文本格式。 该软件是基于Android系统的音乐播放软件,并能够与其他音乐播放软件兼容。 1.3 参考资料 [1] 重庆大学出版社《软件工程》“软件计划与可行性分析” [2] 靳岩、姚尚明人民邮电出版社《Android开发入门与实践》 [3] 可行性分析 [4] 《音乐播放器需求分析书》 [5] 《音乐播放器总体设计说明书》 1.4项目开发计划 实施计划:

阶段名称负责人 需求分析杨挺、李雪梅 总体设计李雪梅、杨挺 详细设计李雪梅、杨挺 软件测试李雪梅、杨挺 在技术方面,编程知识比较缺乏,对有些与项目相关的软件 不熟悉,需进行人员的技术培训(自学为主),技术难点是数据库的构架和软件功能的设计。 2. 总体设计 2.1 项目目的 本项目的目的是开发一个可以播放主流的音乐文本格式的播放器。设计的主要实现功能是播放MP3等格式的音乐文件,并且能控制播放,暂停,停止,音量控制,选择上一曲,选择下一曲,更改皮肤,歌曲列表文件的管理操作,在线播放,读取 存储卡播放等多种播放控制,界面简明,操作简单。 软件系统检测到错误行为时,报告错误,并提示处理操作。 2.2 软件运行环境 硬件:Android操作系统手机 系统软件:Android 2.2 -- 4.0版本 支撑软件:Eclipse 7.5 、ADT 1.5 2.3 需求概述

vlc做流媒体播放器(里面有好多知识点哦亲)

vlc的应用之一:在命令行下的使用 2008-11-28 13:45:34 标签:command休闲line职场vlc 原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明。否则将追究法律责任。https://www.doczj.com/doc/969572137.html,/539865/115910 如果编译得到没有界面的vlc,双击运行后就没法手动选打文件或网络了。在这介绍几个vlc的命令行命令。 1. vlc帮助 vlc --help or vlc --help --advanced 2. vlc的debug log vlc -vv --extraintf=logger 运行的log将会保存在vlc-log.txt中。 3. vlc打开文件 vlc -vv --extraintf=logger d:/01.avi 4. 作为服务器通过rtp往客户端发送ts流 vlc -vvv --extraintf=logger d:/01.avi :sout=#duplicate{dst=rtp{dst=localhost,m ux=ts,port=1234}} 5. 作为客户端接收rtp流 vlc -vv --extraintf=logger rtp://@:1234

vlc的应用之二:vlc的ActiveX及cab 2008-11-28 15:38:01 标签:vlc休闲cab职场ActiveX 原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明。否则将追究法律责任。https://www.doczj.com/doc/969572137.html,/539865/115943 2009-05-14补充:8. Activex的卸载;9. 让vlc自动安装Activex ;10. 关于vlc的Activex的说明。 vlc自带了ActiveX控件--axvlc.dll,在编译完vlc之后的activex文件夹下。ActiveX是个好东西,axvlc.dll可以随意放到任何位置,成功注册之后可以方便的应用在程序和网页之中。可以参考activex文件夹下的test.html和README.TXT。ActiveX控件的接口有第一版和第二版,第一版简单,功能少,已经不再维护建议用第二版本,功能多一点。(参考的[1]) vlc-0.8.6i和vlc-0.9.4的ActiveX注册方法略有不同。 做ActiveX的网页测试之前需要把Internet选项-->安全-->本地Intranet 的安全级别调到最低。Jeremiah的网页测试环境是IE7,其他浏览器未进行测试。 1. vlc-0.8.6i的ActiveX注册 在E:下新建文件夹vlc-0.8.6iActiveX,拷贝vlc-0.8.6i目录下的plugins,libvlc.dll,activex/axvlc.dll到vlc-0.8.6iActiveX/dlls目录下,拷贝activex/test.html到vlc-0.8.6iActiveX下。新建文本文件install.bat 内容如下: regsvr32 dlls\axvlc.dll 双击install.bat后会提示“dlls\axvlc.dll中的DllRegisterServer成功”。然后用打开test.html,文本框输入MRL就可以播放了。

mp3音乐播放器c语言版

需求分析 1引言 随着社会的快速发展,现今社会生活紧张,而欣赏音乐是其中最好的舒缓压力的方式之一,音乐成了我们生活工作中的一个重要的部分。而计算机的普及,让人们能让我们通过播放软件,能更好的听到我们喜欢的音乐。本文档就是为了能更好的设计出一个音乐播放去而编写的。 1.1编写目的: 为明确软件需求、安排项目与进度、组织软件开发与测试,撰写本文档。本文档功项目经理、设计人员、开发人员参考。 1.2项目背景项目背景项目背景项目背景 本项目由老师提出,由学生自主开发,实现播放现今主流的音乐MP3,wma文本格式。 开发软件名称:音乐播放器 项目开发者:岳世崇 1.3项目目的和目标 本项目的目的是开发一个可以播放主流的音乐文本格式,本设计的实现主要功能是播放MP3,wma 格式的音乐文件,并且能控制播放,暂停,停止,音量控制,选择上一曲,选择下一曲,各种播放模式,视觉外观,列表文件等多种播放控制,界面简明,操作简单。 1.4参考资料 百度文库,mci接口调用方法

c语言程序设计——清华大学出版社 c数据结构——清华大学出版社。 2.系统需求分析 根据项目,我们可以获得项目系统的基本需求,一下从不同角度来描述系统的需求。 2.1功能需求 系统的功能需求,我们分成三部分来概括,即播放器的基本控制需求,播放列表管理需求和播放器友好性需求。以下分别描述: 一:播放器的基本控制需求 (1)播放:选择歌曲进行播放。 (2)暂停:输入暂停对应的选项,播放暂停。 (3)继续播放:输入继续播放对应的选项,实现继续播放。 (4)停止播放:输入停止播放对应的选项,实现停止播放。 (5)音量控制:输入音量控制所对应的选项实现音量控制。 (6)上一首,下一首:输入上一首或者下一首对应的选项实现歌曲的切换。 (7)播放模式:列表循环播放,列表顺序播放,随机播放,单曲循环播放,单曲播放的选项,选择播放模式。 (8)删除歌曲:删除列表中不想出现的歌曲 (9)快进/快退:输入相应的选项进入快进和快退功能并实现。 (10)查看文件大小:输入查看文件的大小对应的选项,实现查看文件大小的功能 (11)列表之间的相互切换,可以选择不同路径下的不同播放列表 。 二:播放列表管理 1.添加歌曲:添加歌曲的时候可以在本播放列表下进行添加,也可以选择输入播放列

基于51单片机的音乐播放器设计

题目:音乐播放器 课程设计(论文)任务书

摘要 随着电子技术的发展和计算机越来越普遍的使用,单片机作为这两项技术的有机结合也得到了广泛的应用,在某些领域具有不可替代的作用。音乐播放功能随处都会用到,如,在开发儿童智力的玩具中,等等。目前,基于单片机实现音乐播放,其体积小、价格低、编程灵活等特点在这一领域独领风骚。 单片机的英文名称为single chip microcomputer,最早出现在20世纪70年代,国际上现在已逐渐被微控制器(Microcontroller Unit 或MCU)一词所取代。它体积小,集成度高,运算速度快,运行可靠,功耗低,价格廉,因此在数据采集、智能化仪表、通讯设备等方面得到了广泛应用。而8051单片机在小到中型应用场合很常见,已成为单片机领域的实际标准。随着硬件的发展,8051单片机系列的软件工具也有了C级编译器和实时多任务操作系统RTOS,为单片机编程使用C语言提供了便利的条件;并针对单片机常用的接口芯片编制通用的驱动函数,可针对常用的功能模块,算法等编制相应的函数;C语言模块化程序结构特点,可以使程序模块大家共享,不断丰富,这样就使得单片机的的程序设计更简单可靠,实时性强,效率高。作为测控技术与仪器的学生,掌握8051单片机硬件基础及其相关软件操作,将其应用于现代电子产品中是必要而且重要的,这次课程设计我们的题目是用单片机实验箱系统制作音乐播放器。 本次课程设计主要内容是通过单片机C51语言进行编程,以产生乐曲音符和节拍,把乐谱翻译成计算机语言(音符转换诚成相对应的方波频率即定时器装载初值,节拍转换成相对应的延长时间),并将其预先存储到单片机里,然后根据按键调用再由单片机进行信息处理,在经过信号放大,由喇叭放出乐曲声,实现音乐播放的功能。其主要表现在可以播放十首歌曲,可以用十个数字键控制播放的歌曲,并且能在LCD液晶屏显

MP3播放器使用时的五大禁忌

MP3播放器使用时的五大禁忌!! 随意的在大街上走一圈,我们便能发现各式各样的MP3,配带在人们身上,陪着大家穿梭于城市的大街小巷。MP3所带来的无时无刻音乐享受正成为一种全新的时尚。然后在大家都在全民化使用MP3的时候,你知道一些使用MP3的一些禁忌么?可知道触犯这些禁忌在使用中即有可能对你的人身安全、或MP3带来极大的伤害。 而在国外的一些地方,有专家也指出使用MP3是致病的一个重要因素,随意的使用MP3,甚至可导致年轻人比上一代提早30年耳聋。下面我们就根据52硬件网上的一些资料,为大家介绍一下目前最主要的五种使用MP3一定要注意的禁忌。并为大家提出相应的解决方法。 禁忌一:音量调节得过大 很多用户听MP3的时候,总是喜欢听得屁较清楚,如果就尽量的把音量调高。而MP3一般而言最大音量可以高达80分贝,相当于一台割草机发出的声音,这种声音能直接损伤听力。MP3调到大音量带来的失真会使高音刺耳、中音不清、低音浑浊,而失真属于噪音的一种,也会给你的MP3和耳机带来一定的损伤。 建议:MP3的总音量控制在最大音量的1/4-1/3。此外,每次听完音乐之后,养成把音量调节旋钮关至最小的习惯。【资讯第一播报https://www.doczj.com/doc/969572137.html,】 禁忌二:长时间收听 有些用户听MP3的时候,听到自己的喜欢听的歌曲总是喜欢一次听个够。听MP3要讲究劳逸结合,长时间听MP3会造成耳朵压力过重造成耳朵超负荷工作,致使听力下降损害健康。 建议:一般情况下根据所收听MP3音乐的类型的不同,长短也有不同。过分激烈的音乐,比如摇滚、快速流行音乐、大动态交响乐等,1小时左右应该休息一下,也就是听一张CD的长度应该休息15分钟左右。轻音乐,人声,较慢的流行音乐等可以100分钟左右休息一次。当然根据耳塞耳机器材的不同时间也有变化,上面说的时间是标准耳塞的长度,插入耳道的密闭式耳塞应该减少20%的时间,而耳机可以适当的增加15%左右的时间。 禁忌三:佩戴耳塞收听 MP3配置的耳塞式耳机被直接塞进耳朵里,能将声音信号提高9分贝,时间长了会对耳膜造成伤害。而还有为了追求强劲低频,很多耳塞使用长长的笛管式低音谐振和防漏音设计,并把耳塞的外形与耳朵的形状相配合,使耳塞与耳孔贴紧,直接利用耳朵的耳道作为低音共振腔,这样就能听到更强劲的音乐。 从技术上说,这当然是一种巧妙的设计,但它对耳朵带来的伤害是极为严重的。短期使用时,由于人体具有的修复功能,造成的影响还不大。但是长期使用,无疑会造成严重的听力损害。现在一些厂家也尽量迎合国内消费者的偏好,现在还推出了所谓的“特重低音”耳塞,用一个凸型的薄膜集中了声音能量对准耳孔,以增加低频效果。使用这些耳塞,无疑会造成更严重的伤害。【资讯第一播报https://www.doczj.com/doc/969572137.html,】 建议:使用头戴式耳机显然比耳塞要好的多,这就是为什么以前销往欧洲的随身听大部分配备头戴式耳机的原因了,因为耳塞曾经对欧洲的年轻人造成伤害。 禁忌四:嘈杂环境中听MP3

流媒体常识工具格式转换播放软件使用介绍

流媒体常识工具格式转换播放软件使用介绍流媒体常识工具格式转换播放软件使用介绍目录: 1. 流媒体常识工具格式转换播放软件使用介绍 2.常见视频格式之间如何转换 3.将MTV转成mp3 4. 将MP3转刻成CDA光盘 5.将MIDI转为WAVE 6.制作RM音乐 7.如何分割asf文件 8.视频编码/解码器问答 9.修复下载后的电影 10.分割合并MP3歌曲 11.从视频文件中提取声音 12.光盘刻录 13.巧用摄像头制作VCD 14.视频同步字幕制作 15.视频编辑常见问题 16.流媒体编辑魔术师AsF Tools 17.最简单的VCD制作 流媒体常识工具格式转换播放软件使用介绍 Q.为什么有的电影没有图像,只有声音?

在观看电影的时候,可能会遇到只有声音,没有图像的现象,这时你需要看看自己是否安装了DIVX插件(看 MPEG4的工具),没有安装一定会出现上述现象,而如果你安装了或者观看的不是MPEG4的电影,那从锌赡?是网速的问题,可能是你的网速慢或者是在线观看的人太多了,服务器过载的缘故,都会引起上述现象本站上网工具包提供DIVX插件的下载 Q.rm文件如何解决国语和粤语的双声道问题? 一些文件如rm asf有的时候国语和奥语是混合在一些的,而realplaywindows mediaplay一般都是不能分开声道的其实你可以采用如下简单的方法解决:双击任务栏上的喇叭图标,然后将Wave Output向右播到头即可解决但这并不是100%全能解决的,一些电影文件是无法解决这个问题的,只能认命了目前realfox软件也可以解决双声道问题,但它采用的方法也是和前面所说的一样,因此也不是100%能解决问题了 Q.ram文件是什么,如果才能找到真实的下载地址? ram一般都很小(几十个字节),它是一个导航文件下载后用记事本打开,然后你就会看到真实的下载地址了 Q:encoder不能设置用户权限访问 A:因为real没有在encoder设置用户访问权限!! Q:跑RealServer的服务器组播时的CPU,内存需求情况? A:RealServer中的组播是将一个现场直播流同时传递给多个客户端,而 无需为每一客户的连结发送一个单独的数据流,客户端只需连结到这个 数据流,而不是连结到RealServer服务器,从而降低带宽的使用为了 利用组播技术所带来的优越,在RealServer与Realplayer客户端之间的 所有设备必须是支持组播技术的,包括之间的路由器交换机和其他 的网络设备! 使用组播能够减少带宽的使用,用一般满足100个600k 连接的机器配置就行了! A:音轨的问题可以这样解决,下载smart ripper ,这个工具可以把DVD的光盘的vob文件和它的音轨合成一个新的 VOB文件,这样子视频和音轨就能在同一个文件里,随便你用FlaskMPEG 或者其他工具转化了 A:flash在smil语言中插入的时候用realplay播放是没有声音用realplay plus播放没有问题为什么?给real公司发过信也没有明确的回答!!! Q:*.dat转化为*.rm格式的软件?

MP3音乐播放器软件课程设计报告(MFC)

课程设计说明书 课程设计名称:软件综合课程设计 课程设计题目:音频播放器程序的设计与实现学院名称:信息工程学院

电子信息工程专业课程设计任务书 正文: 目录 引言 (5) 一、设计程序的目的与要求 (6)

目的 (6) 要求 (6) 二、方案实现与调试 (6) 总体设计 (6) 1、实现功能 (6) 2、功能模块图 (7) 详细设计 (7) 1、界面布局 (7) 2、各模块功能设计 (8) 2.1处理“打开”按钮 (9) 2.2处理“播放”按钮 (9) 2.3处理“暂停”按钮 (9) 2.4处理“停止”按钮 (9) 2.5处理“音量”按钮 (10) 2.6处理“退出”按钮 (10) 3 操作步骤 (10) 三、课程设计分析与总结 (11) 分析 (11) 总结 (11) 附录 (13) 关键程序清单 (13)

参考文献 (20) 引言 MP3播放器的设计是利用MFC应用程序、媒体控制接口MIC 的基本知识而设计的。 1.1 MFC简介 MFC是Visual C++是核心。MFC类库将所有图形用户界面的元素如窗口、菜单和按钮等都以类的形式进行了封装,MFC AppWizard 向导根据继承性利用MFC派生出自己的类,并对Windows应用程序进行了分解,利用MFC派生类对应用程序重新进行组装,同时还规定了应用程序中各个MFC派生类对象之间的相互联系,实现了标准Windows应用程序的功能,这就是向导生成的所谓MFC应用程序框架。每个MFC类都包括了一些函数,函数放到类中,符合C++编程方法。这些函数,必须通过类定义对象才能使用[1]。 1.2 MCI简介 MCI(Media Control Interface)媒体控制接口是MircroSoft提供的一组多媒体设备和文件的标准接口,它的好处是可以方便地控制绝大多数多媒体设备包括音频、视频、影碟、录像等多媒体设备,而不

基于STM32 MP3播放器设计分析

基于STM32 MP3播放器设计 学院:XXXXXXXXXXX 专业班机:XXXXXXXX 姓名XXXXX 学号:XXXXXXXX

1.1 本课题的提出及意义 MP3音频播放器的最合理工作速度为30Mips,而一个典型的视频媒体播放器的理想速度则为175Mips,所以提高MP3的工作速度,以及改善MP3的音质是最关键的,也是亟待解决的问题。 MP3是一种典型的嵌入式设备,而现在市场上比较常见的是闪存式MP3。由于闪存式MP3的容量限制,使它存储歌曲数目较少,在功能上也很难实现多样化[1]。而硬盘式MP3的多功能及大容量,也必将受到不少消费者的喜爱。 MP3播放器一般分成3个部分:CPU、MP3硬件解码器存储器。其中可以将前两部分集成在一起,即带MP3硬件解码器的CPU;或将后两部分集成在一起,即集成硬件解码、D/A转换及音频输入。存储器可以是Flash存储器或硬盘[2]。通过用MP3编码技术,可以得到大约12:1压缩的有损音乐信号。 1.2 研究现状 MP3全称是MPEG Layer 3,狭义的讲就是以MPEG Layer 3标准压缩编码的一种音频文件格式。自韩国世韩(Seahan)公司1998年推出世界上第一台MP3随身听以来, MP3播放器以其小巧的外形,不错的近乎于CD的音质,前卫的功能,越来越受到消费者的青睐,也就成为业界甚至大众媒体关注的一个热门话题[3]。在市场消费刺激下,各大公司纷纷推出了自己的mp3播放器产品,IC供应商提供了众多的MP3解码芯片及其解决方案。除了Micronas方案(MAS3507+DAC3550),还有台湾创品方案(T33510,T33520)、美国SigmaTel方案(STMP3400)和TI的DA-250解决方案。这使mp3播放器的研制与生产变得更加容易,成本也大大降低,市场更加广阔[4]。 2 硬件设计 2.1整体方案 综述

流媒体MP3播放器教程

基于libmad 的简单MP3流媒体播放器的实现.介绍 本文在Fedora 5 Linux 下实现了一个基于libmad 的mp3 流媒体播放器。此流媒体播放器可以播放基于HTTP 1.1 协议传输的MP3 流媒体数据。 基本原理是:从HTTP 服务器获得MP3 媒体信息,然后通过网络传输把MP3 数据以数据流的形式接收到MP3 流媒体播放器客户端,由客户端通过libmad 解码MP3 数据流,得到PCM 音频数据,写入音频设备,播放音乐。本文的流媒体播放器只是实现了必要的简单功能,没有考虑太多情况。比如,没有考虑实时播放控制,这样的话就不能随意选取播放点进行播放。 本文的MP3 流媒体播放器创建两个线程,使用两个缓冲区保存MP3 数据,可以一边下载数据,一边播放音乐。编译运行此MP3 流媒体播放器需要安装libmad (https://www.doczj.com/doc/969572137.html,/prodUCts/mad/) 以及ALSA(Advanced Linux Sound Architecture) (https://www.doczj.com/doc/969572137.html,)相关的软件。ALSA包括4部分,分别是sound driver, sound library , sound utilities 以及tools。至少应该安装sound driver, sound library 。编译程序时连接库的选项是:-lmad -lasound -lpthread。 本文的MP3 流媒体播放器使用双缓冲区,一个是数据接收缓冲区,另一个是数据解码缓冲区。主程序结构如下图所示,图中的蓝色线表示数据流向。

图1:MP3 流媒体播放器主程序结构图 2.libmad简介 MAD (libmad)是一个开源的高精度MPEG 音频解码库,支持MPEG-1(Layer I, Layer II 和LayerIII(也就是MP3)。LIBMAD 提供24-bit 的PCM 输出,完全是定点计算,非常适合没有浮点支持的平台上使用。使用libmad 提供的一系列API,就可以非常简单地实现MP3 数据解码工作。在libmad 的源代码文件目录下的mad.h 文件中,可以看到绝大部分该库的数据结构和API 等。 本文用到的libmad 中的主要数据结构有:struct mad_stream, struct mad_synth, struct mad_frame。它们的定义如下: 清单1:libmad 中的主要数据结构 struct mad_stream { unsigned char const *buffer; /* input bitstream buffer */ unsigned char const *bufend; /* end of buffer */

手把手教您用MFC做MP3音乐播放器

打开vc6.0,建立如图所示mfc工程文件 选择基于对话框的确定 删除所有空间,建立如图所示对话框

属性如下: 播放IDC_open; 添加IDC_fileopen; 暂停IDC_pause; 删除IDC_del; 停止IDC_stop; 退出IDC_exit; 音乐名编辑框IDC_filename;音量控制滑块IDC_SLIDER1;音量控制编辑框IDC_vol; 建立类向导对应如下:

在工程文件,右键,插入,bitmap位图 引入你想插入的背景图,必须是bmp格式的 进入你的dlg.cpp文件

在onpaint函数下添加代码 void CMp3Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon);

音乐播放器设计文档

生产实习报告 题目:音乐播放器 学生姓名:张凡 学号: 201220220123 班级: 1222201 专业:数字媒体技术 指导教师:张金 2015年08 月08日

目录 一、引言 (3) 1.1 项目背景 (3) 1.2 项目研究的目的 (4) 1.3 安卓简介 (4) 二.功能分析 (5) 2.1 功能需求分析 (5) 2.2 系统性能需求 (6) 2.3 运行环境需求 (6) 三.程序详细设计 (6) 3.1 主界面的设计 (6) 3.2 播放界面设计 (11) 3.3 其他功能 (14) 四.调试与运行 (18) 4.1 调试 (18) 4.2 运行结果 (19) 五.总结 (21)

一、引言 1.1 项目背景 当今社会的生活节奏越来越快,人们对手机的要求也越来越高,由于手机市场发展迅速,使得手机操作系统也出现了不同各类,现在的市场上主要有三个手机操作系统,symbian,Windows mobile,以及谷歌的Android操作系统,其中占有开放源代码优势的Android系统有最大的发展前景。那么能否在手机上拥有自己编写的个性音乐播放器呢?答案是:肯定的,谷歌Android系统就能做到。本文的音乐播放器就是基于谷歌Android手机平台的播放器。 随着计算机的广泛运用,手机市场的迅速发展,各种音频视频资源也在网上广为流传,这些资源看似平常,但已经渐渐成为人们生活中必不可少的一部分了。于是各种手机播放器也紧跟着发展起来,但是很多播放器一味追求外观花哨,功能庞大,对用户的手机造成了很多资源浪费,比如CPU,内存等的占用率过高,在用户需要多任务操作时,受到了不小的影响,带来了许多不便,而对于大多数普通用户,许多功能用不上,形同虚设。针对以上各种弊端,选择了开发多语种的音频视频播放器,将各种性能优化,继承播放器的常用功能,满足一般用户(如听歌,看电影)的需求,除了能播放常见格式的语音视频文件,高级功能:还能播放RMVB格式的视频文件。此外,还能支持中文、英文等语言界面。

《基于Android平台的音视频流媒体播放器》

目录 1. 绪论 (2) 1.1. 提出问题 (2) 1.2. 研究现状 (2) 1.3. 研究思路与方法 (4) 2. Android操作系统整体结构分析 (6) 2.1. Android系统简介 (6) 2.2. Android整体结构 (7) 2.2.1. Android 架构 (7) 2.2.2. 特征 (9) 2.3. Android 应用组件 (9) 2.3.1. 活动(Activity) (10) 2.3.2. 服务(Services) (11) 2.3.3. 广播接收者(Broadcast receivers) (12) 2.3.4. 内容提供者(Content providers) (12) 2.4. Android NDK工具 (13) 3. FFmpeg流媒体平台介绍与研究 (14) 3.1. FFmpeg简介 (14) 3.2. FFmpeg 的编译与运行 (14) 4. 流媒体播放器应用分析 (16) 4.1. 系统功能需求分析 (16) 4.2. 系统整体结构需求分析 (17) 4.3. 系统业务流程分析 (18) 4.3.1. 媒体播放模块业务流程 (18) 4.3.2. 媒体文件管理模块业务流程 (19) 4.3.3. 系统设置模块业务流程 (21) 5. 流媒体播放器应用设计 (22) 5.1. 系统设计模型 (22) 5.2. 系统UI设计 (23) 5.2.1. 媒体播放模块设计 (23)

5.2.2. 媒体文件管理模块设计 (25) 5.2.3. 系统设置模块设计 (29) 5.3. 系统数据库设计 (31) 5.3.1. SQLite简介 (31) 5.3.2. 播放器库表说明 (31) 6. Android平台的流媒体播放器应用实现 (33) 6.1. Android 应用程序开发 (33) 6.1.1. Android 开发环境 (33) 6.1.2. Android 应用开发特点 (34) 6.2. FFmpeg移植 (36) 6.3. FFmpeg音视频解码 (39) 6.4. 流媒体播放功能的开发与实现 (41) 总结 (46) 致谢 ..................................................... 错误!未定义书签。参考文献 .. (47)

MP3音乐播放器课程设计

Java程序设计 课程设计说明书 简单音乐播放器 起止日期:2011年12月6日至2012年1月4日 学生姓名XXX 班级软件工程093班学号09408300310 成绩 指导教师 计算机与通信学院 2011年12 月28日

目录 一、绪论 (1) 1.1 课题背景 (1) 1.2 课程设计目的 (1) 1.4 课程设计实验环境 (1) 1.5 课程设计要求 (1) 二、课程系统分析 (3) 2.1 系统分析 (3) 2.1 功能分析 (3) 三、系统设计 (4) 3.1 系统功能结构图 (4) 3.2 模块功能设计 (4) 3.2.1处理“添加”按钮 (4) 3.2.2处理“播放”按钮 (4) 3.2.3 处理“停止”按钮 (4) 3.2.4 处理“单曲循环”按钮 (5) 四、系统实现 (6) 4.1 系统主界面的实现 (6) 4.2 系统主要功能实现 (6) 4.2.1系统主界面及关键代码: (6) 4.2.2添加文件的界面和代码: (9) 4.2.3 播放音乐的界面和代码: (11) 4.2.4 单曲循环的界面和代码: (12) 五、设计总结 (15) 5.1 设计体会及评价 (15) 参考文献 (16) 致谢 (17)

一、绪论 1.1 课题背景 随着社会电子音乐文件的与日俱增,作为现在最流行的音乐文件*.mp3,*.wav文件的数量和规模也在比以往的任何时候要多,不论是电台DJ需要使用方便而有效地管理自己所使用的音乐文件,还是个人。在计算机日益普及的今天,若采用一套有效的音乐播放器。将自己所收藏的大量的音乐文件能随时随地的播放,这将方便于众用户听音乐的需求。通过使用本音乐播放器能为音乐爱好者带来意想不到的收获。 1.2 课程设计目的 《JAVA程序设计》是计算机相关专业的必修专业基础课程,其实践性、应用性很强。实践教学环节是必不可少的一个重要环节。本课程的程序设计专题实际是计算机相关专业学生学习完《JAVA程序设计》课程后,进行的一次全面的综合训练,JAVA程序设计的设计目的是加深对理论教学内容的理解和掌握,使学生较系统地掌握程序设计及其在网络开发中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用软件工程为基础进行软件开发、并在实践应用方面打下一定基础。 1.4 课程设计实验环境 程序运行在安装有windows操作系统的计算机上(台式机和笔记本),兼容windows 2K/XP/Vista/7 计算机硬件要求: 1.CPU:1G; 2.内存:512M. ; 3.显卡:256M显存; 文件播放:需要安装有声卡、要求安装有语音库。 JA VA程序设计语言及相应的集成开发环境,J2SDK和ECLIPSE开发工具。 1.5 课程设计要求 按课程设计指导书提供的课题,要求学生在自行完成各个操作环节,并能实现且达到举一反三的目的,完成一个项目解决一类问题。要求学生能够全面、深入理解和熟练掌握所学内容,并能够用其分析、设计和解答类似问题;对此能够较好地理解和掌握,能够进行简单分析和判断;能编写出具有良好风格的程序;

IPTV机顶盒的流媒体播放器设计

第30卷 第7期 2008年7月武 汉 理 工 大 学 学 报JOURNA L OF WUHAN UNIVERSIT Y OF TECHN OLOG Y Vol.30 No.7 J ul.2008 IPTV 机顶盒的流媒体播放器设计 龙 欣1,徐 宁2 (1.武汉理工大学信息工程学院,武汉430070;2.武汉理工大学计算机科学与技术学院,武汉430070) 摘 要: 介绍了IPTV 机顶盒流媒体播放器的设计过程,利用live555开源代码中playCommon.cpp 的功能,结合IPTV 机顶盒的软件结构设计开发了IPTV 机顶盒的传输模块。然后将这个传输模块通过消息队列与中间件连接,同时通过播放模块的入口函数与播放模块连接,最后组成了IPTV 机顶盒的流媒体播放器。该播放器经测试,性能稳定。 关键词: live555; playCommon.cpp ; 流媒体播放器; IPTV 机顶盒 中图分类号: TP 37文献标识码: A 文章编号:167124431(2008)0720156202 Design of Streaming Media Player of IPTV STB L ON G Xi n 1,X U N i ng 2 (1.School of Information Engineering ,Wuhan University of Technology ,Wuhan 430070,China ; 2.School of Computer Science and Technology ,Wuhan University of Technology ,Wuhan 430070,China ) Abstract : This paper introduced the design of streaming media player of IPTV STB.Firstly ,the principle of playCommon.cpp in live555was introduced.Then combining with the software framework of the IPTV STB ,the transport module of streaming media player was designed.Secondly ,this module was connected with middleware through message queuing and at the same time connected with player module through the entrance of the player.At last it came to be a streaming media player of IPTV STB.The media player passed through tests and worked well. K ey w ords : live555; playCommon.cpp ; streaming media player ; IPTV STB 收稿日期:2008203228. 基金项目:国家自然科学基金(60572015). 作者简介:龙 欣(19842),女,硕士生.E 2mail :lx.hawaii @https://www.doczj.com/doc/969572137.html, 开源代码live555是用来实现流媒体传输功能的SD K 。用该SD K 中test Pro gs 文件夹中的play 2Common.cpp 来设计IPTV 机顶盒的传输模块,并与播放模块一起构成IPTV 机顶盒的流媒体播放器的过程。playCommon.cpp 是连接服务器和客户端的桥梁,它的工作原理就是客户端向服务器请求数据时,从服务器的URL 处获得SDP 描述信息并根据SDP 创建多媒体会话,最后播放数据流的过程。 1 IPTV 机顶盒流媒体播放器设计 1.1 IPTV 机顶盒软件结构 机顶盒的软件代码实现分4部分:硬件驱动、操作系统、中间件、应用层[1],如图1所示。 1)硬件驱动 连接底层硬件和上层操作系统。2)操作系统 这里用的是免费的开源代码Linux 。3)中间件 隔离上层应用层与底层操作系统及硬件的软件适配层。中间件的核心模块主要包括:(1)浏览器:从服务器端获得URL ,并将对应的EP G 页面显示出来。(2)图形用户界面管理:为应用程序提供用户界面控制(如按钮、列表)以及图形图像绘制等图形功能[2]。4)应用层 实现对音、视频媒体文件的播放。 1.2 IPTV 机顶盒流媒体播放器系统结构 Live555开源代码中playCommon.cpp 实现了以电脑作为接收终端,用VLC 软件进行接收并播放,最后

基于android的在线音乐播放器的设计与实现开题报告

本科生毕业设计(论文)开题报告 论文题目:基于android的在线音乐播放器的设计与实现 学院:软件学院 专业:计算机科学与技术 学生姓名: 学生班级: 学生学号: 指导教师:

基于android的在线音乐播放器的设计与实现 一、课题的研究目的和意义 现如今社会生活节奏日益加快,人们在忙碌的生活中欣赏音乐是最好的舒缓压力的方式之一。随着移动设备的日益完善,我们大家都已经有了在手机上听自己喜欢歌曲的习惯,以往的做法是用数据线或者蓝牙等无线设备将PC上的歌曲复制几首到手机当中,反反复复的听,等到听厌了以后,再次装一些歌曲进去,如此反复,非常的麻烦。因此,如果在我们的手机上能实现在线听歌,这将会带来极大的方便。 本项目是一款基于Android手机平台的音乐播放器,使Android手机拥有个性的多媒体播放器,是手机显得更生动灵活化,与人们更为方便,让手机主人随时随地处于音乐的旋律之中。本设计实现的重要功能是播放Mp3格式的音乐文件,并且能够控制音乐的播放,暂停,显示歌手信息,歌曲专辑等功能。本项目还可以使人们生活更加多样化,也使设计者更加熟悉Android的技术和其它在市场上的特点。 二、国内外发展状况 1. 目前中国拥有世界上最大的手机用户群,Android在中国的前景十分广阔,首先是有成熟的消费者,Android社区是分红或,这些社区为Android在中国的普及做了很好的推广作用。国内厂商和运营商也纷纷加入了Android阵营,保过中国移动、中国联通、中心通讯、华为通讯、联想等大企业,同时还不仅仅局限于手机,国内厂家也陆续退出了采用Android系统的MID产品,比较著名的包括由Rock chip和蓝魔推出的同时具备高清播放和智能系统的音乐汇W7和2010年推出的原道N5,我们可以预见Android也将会被广泛应用在国产智能上网设备上,将进一步扩大Android系统的应用范围。 2. 国外Android市场正在如日中天的扩展,根据市场调研机构NPDGroup最近发布的一份报告称,今年第一季度基于Android操作系统的智能手机在美国智能手机总销售量中所占比例达到28%,超越苹果iPhone。2012年另一家市场研究公司comScore发布报告称,第三季度三星和Android操作系统仍在美国移动市场上占据主导地位。报告显示,在对3万多名美国移动用户进行调查后发现,谷歌Android平台第三季度仍在美国市场上占据主导地位,所占份额为52.5%,比第二季度增长近1个

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

本文在 Fedora 5 Linux 下实现了一个基于 libmad 的 MP3 流媒体播放器。此流媒体播放器可以播放基于 HTTP 1.1 协议传输的 MP3 流媒体数据。 基本原理是:从 HTTP 服务器获得 MP3 媒体信息,然后通过网络传输把 MP3 数据以数据流的形式接收到 MP3 流媒体播放器客户端,由客户端通过 libmad 解码 MP3 数据流,得到 PCM 音频数据,写入音频设备,播放音乐。本文的流媒体播放器只是实现了必要的简单功能,没有考虑太多情况。比如,没有考虑实时播放控制,这样的话就不能随意选取播放点进行播放。 本文的 MP3 流媒体播放器创建两个线程,使用两个缓冲区保存 MP3 数据,可以一边下载数据,一边播放音乐。编译运行此 MP3 流媒体播放器需要安装 libmad (https://www.doczj.com/doc/969572137.html,/products/mad/) 以及 ALSA(Advanced Linux Sound Architecture) (https://www.doczj.com/doc/969572137.html,)相关的软件。ALSA包括4部分,分别是 sound driver, sound library , sound utilities 以及 tools。至少应该安装 sound driver, sound library 。编译程序时连接库的选项是:-lmad -lasound -lpthread。 本文的 MP3 流媒体播放器使用双缓冲区,一个是数据接收缓冲区,另一个是数据解码缓冲区。主程序结构如下图所示,图中的蓝色线表示数据流向。 图 1:MP3 流媒体播放器主程序结构图

C#.NET2005实现一个流媒体播放器

C#.NET2005实现一个流媒体播放器 2007-04-05 16:38 用C#.NET2005实现一个流媒体播放器,感觉还是不错的,就是调用了Windows 中的一个动态连接库——Quarz.dll。我写的是一个DirectShow多媒体播放器。支持目前为止的大部分格式。代码共享一下: using System; using System.Collections.Generic; using https://www.doczj.com/doc/969572137.html,ponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using QuartzTypeLib;//这个就是Quarz.dll转换后的Dll文件 namespace myMedia { public partial class Form1 : Form { public Form1() { InitializeComponent(); } // private https://www.doczj.com/doc/969572137.html,ponentModel.IContainer components; private const int WM_APP = 0x8000; private const int WM_GRAPHNOTIEY = WM_APP + 1; private const int EC_COMPLETE = 0x01; private const int WS_CHILD = 0x40000000; private const int WS_CLIPCHILDREN = 0x2000000; private FilgraphManager m_objFilterGraph = null; private IBasicAudio m_objBasicAudio = null; private IVideoWindow m_objVideoWindow = null; private IMediaEvent m_objMediaEvent = null; private IMediaEventEx m_objMediaEventEx = null; private IMediaPosition m_objMediaPosition = null; private IMediaControl m_objMediaControl = null; enum MadiaStatus { None, Stopped, Paused, Running }; private MadiaStatus m_CurrentStatus = MadiaStatus.None; private void CleanUp() { if (m_objMediaControl != null) {

相关主题
文本预览
相关文档 最新文档