音乐解码器实现
一、下载音频数据
1、解析URL,如https://resource.alilo.com.cn/res/24,6a59891ab368.mp3
1)resource.alilo.com.cn为主机名,需要解析成对应的ip地址,端口号默认是80
getaddrinfo解决了把主机名和服务名转换成套接口地址结构的问题。POSIX中的函数原型: #include<netdb.h> int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result ); 返回0: 成功 返回非0: 出错
2、连接ip服务器,并发送http get请求(要熟悉http get/post通信协议)
snprintf(request, URL_MAX, "GET %s HTTP/1.0\r\n" "User-Agent: ipc\r\n" "Host: %s:%s\r\n" "Accept: audio/*\r\n" "Connection: Keep-Alive\r\n" "Range: bytes=%u-\r\n" "\r\n", resource, host, port, offset > 0 ? offset : 0);
ret = send(sock, request, strlen(request), 0);
服务器返回的部分应答如下
Server: Tengine Content-Type: audio/mpeg Content-Length: 4105390 Connection: keep-alive Date: Tue, 16 Oct 2018 13:08:13 GMT Last-Modified: Fri, 20 Apr 2018 01:59:02 GMT ETag: "5ad94966-3ea4ae" Expires: Wed, 31 Oct 2018 13:08:13 GMT Cache-Control: max-age=1296000 Accept-Ranges: bytes Via: cache6.l2st3-2[ 3485.420000] [gk_pcm_prepare 564] count= 3 [0,200-0,H], cache17.l2st3-2[197,0], kunlun6.cn1361[0,206-0,H], kunlun9.cn1361[14,0] Age: 510325 Ali-Swift-Global-Savetime: 1539958704 X-Cache: HIT TCP_HIT dirn:7:228616357 X-Swift-SaveTime: Fri, 19 Oct 2018 14:18:24 GMT X-Swift-CacheTime: 2592000 Content-Range: bytes 0-4105389/4105390 Timing-Allow-Origin: * EagleId: b706e79d15402056179996108e
3、通过分析http头信息,可获取MP3文件大小,然后调用recv接收MP3数据,缓存到download_ring_buf里;
二、音频数据解码(mpg123和ffmpeg)
1、mpg123开源解码器获取
. download url: https://nchc.dl.sourceforge.net/project/mpg123/mpg123/1.25.6/mpg123-1.25.6.tar.bz2 2. make command: mpg123-1.25.6$ export PATH=/home/tim/bin/goke-compile-tools/4.6.1/usr/bin:$PATH mpg123-1.25.6$ ./configure --help mpg123-1.25.6$ mkdir out mpg123-1.25.6$ ./configure --host=arm-linux CC=arm-linux-gcc --with-default-audio=dummy --prefix=/home/tim/work/ext_disk/disk2/ipc/mpg123/mpg123-1.25.6/out mpg123-1.25.6$ make mpg123-1.25.6$ make install
1.1 mpg123初始化
static int open_libmpg123(mp3_private_data_t *pri) { int ret = 0; pri->mh = mpg123_new(NULL, &ret); if (pri->mh == NULL || ret != MPG123_OK) { RLOGE("mpg123_new fail"); mpg123_exit(); return -1; } mpg123_param(pri->mh, MPG123_FORCE_RATE, 16000, 0); mpg123_param(pri->mh, MPG123_ADD_FLAGS, MPG123_FORCE_STEREO, 0); //mpg123_param(pri->mh, MPG123_ADD_FLAGS, MPG123_SEEKBUFFER, 0); //mpg123_param(pri->mh, MPG123_ADD_FLAGS, MPG123_NO_RESYNC, 0); //mpg123_param(pri->mh, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0); //mpg123_param(pri->mh, MPG123_ADD_FLAGS, MPG123_SKIP_ID3V2, 0); //mpg123_param(pri->mh, MPG123_FEEDPOOL, 4096, 0); mpg123_feature(MPG123_FEATURE_OUTPUT_16BIT); if (mpg123_open_feed(pri->mh) != MPG123_OK) { RLOGE("mpg123_open_fd fail"); mpg123_delete(pri->mh); return -1; } return 0; }
2、FFmpeg编译
ffmpeg with libfdk-aac ./configure --cross-prefix=arm-goke-linux-uclibcgnueabi- --enable-cross-compile --target-os=linux --arch=arm --cc=arm-goke-linux-uclibcgnueabi-cc --cxx=arm-goke-linux-uclibcgnueabi-g++ --prefix=/home/tim/work/disk10/ipc/ffmpeg/ffmpeg-4.0.2/out --disable-static --enable-shared --disable-programs --disable-doc --disable-avdevice --disable-swscale --disable-postproc --disable-avfilter --disable-error-resilience --disable-pixelutils --disable-encoders --disable-muxers --disable-indevs --disable-outdevs --disable-filters --disable-v4l2_m2m --disable-parsers --enable-parser=aac --enable-parser=flac --enable-parser=mpegaudio --disable-protocols --enable-protocol=file --enable-protocol=hls --enable-protocol=http --enable-protocol=httpproxy --enable-protocol=tcp --enable-protocol=udp --disable-decoders --enable-decoder=amrnb --enable-decoder=amrwb --enable-decoder=flac --enable-decoder=mp3 --enable-decoder=libfdk_aac --enable-libfdk-aac --extra-cflags="-I/home/tim/work/disk10/ipc/ffmpeg/fdk-aac-0.1.6/out/include" --extra-ldflags="-L/home/tim/work/disk10/ipc/ffmpeg/fdk-aac-0.1.6/out/lib" --disable-bsfs
3、使用mpg123的接口mpg123_decode()进行解码