Android 音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停和调整音量(附源码下载)
项目地址
https://github.com/979451341/OpenSLAudio
OpenSL ES 是基于NDK也就是c语言的底层开发音频的公开API,通过使用它能够做到标准化, 高性能,低响应时间的音频功能实现方法。
这次是使用OpenSL ES来做一个音乐播放器,它能够播放m4a、mp3文件,并能够暂停和调整音量
播放音乐需要做一些步骤
1.创建声音引擎
首先创建声音引擎的对象接口
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
然后实现它
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
从声音引擎的对象中抓取声音引擎
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
创建"输出混音器"
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req);
实现输出混合音
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
2.创建声音播放器
创建和实现播放器
// realize the player
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void)result; // get the play interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
(void)result;
3.设置播放缓冲
数据格式配置
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_8,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};
数据定位器 就是定位要播放声音数据的存放位置,分为4种:内存位置,输入/输出设备位置,缓冲区队列位置,和midi缓冲区队列位置。
数据定位器配置
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
得到了缓存队列接口,并注册
// get the buffer queue interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
(void)result; // register callback on the buffer queue
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
assert(SL_RESULT_SUCCESS == result);
(void)result;
4.获得其他接口用来控制播放
得到声音特效接口
// get the effect send interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_EFFECTSEND,
&bqPlayerEffectSend);
assert(SL_RESULT_SUCCESS == result);
(void)result;
得到音量接口
// get the volume interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_VOLUME, &bqPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
(void)result; // set the player's state to playing
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
(void)result;
5.提供播放数据
打开音乐文件
// convert Java string to UTF-8
const char *utf8 = (*env)->GetStringUTFChars(env, filename, NULL);
assert(NULL != utf8); // use asset manager to open asset by filename
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
assert(NULL != mgr);
AAsset* asset = AAssetManager_open(mgr, utf8, AASSET_MODE_UNKNOWN); // release the Java string and UTF-8
(*env)->ReleaseStringUTFChars(env, filename, utf8); // the asset might not be found
if (NULL == asset) {
return JNI_FALSE;
} // open asset as file descriptor
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
assert(0 <= fd);
AAsset_close(asset);
设置播放数据
SLDataLocator_AndroidFD loc_fd = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
SLDataSource audioSrc = {&loc_fd, &format_mime};
6.播放音乐
播放音乐只需要通过播放接口改变播放状态就可以了,暂停也是,停止也是,但是暂停必须之前的播放缓存做了才行,否则那暂停就相当于停止了
result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, isPlaying ?
SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED);
7.调解音量
SLVolumeItf getVolume()
{
if (fdPlayerVolume != NULL)
return fdPlayerVolume;
else
return bqPlayerVolume;
} void Java_com_ywl5320_openslaudio_MainActivity_setVolumeAudioPlayer(JNIEnv* env, jclass clazz,
jint millibel)
{
SLresult result;
SLVolumeItf volumeItf = getVolume();
if (NULL != volumeItf) {
result = (*volumeItf)->SetVolumeLevel(volumeItf, millibel);
assert(SL_RESULT_SUCCESS == result);
(void)result;
}
}
8.释放资源
关闭app时释放占用资源
void Java_com_ywl5320_openslaudio_MainActivity_shutdown(JNIEnv* env, jclass clazz)
{ // destroy buffer queue audio player object, and invalidate all associated interfaces
if (bqPlayerObject != NULL) {
(*bqPlayerObject)->Destroy(bqPlayerObject);
bqPlayerObject = NULL;
bqPlayerPlay = NULL;
bqPlayerBufferQueue = NULL;
bqPlayerEffectSend = NULL;
bqPlayerMuteSolo = NULL;
bqPlayerVolume = NULL;
} // destroy file descriptor audio player object, and invalidate all associated interfaces
if (fdPlayerObject != NULL) {
(*fdPlayerObject)->Destroy(fdPlayerObject);
fdPlayerObject = NULL;
fdPlayerPlay = NULL;
fdPlayerSeek = NULL;
fdPlayerMuteSolo = NULL;
fdPlayerVolume = NULL;
} // destroy output mix object, and invalidate all associated interfaces
if (outputMixObject != NULL) {
(*outputMixObject)->Destroy(outputMixObject);
outputMixObject = NULL;
outputMixEnvironmentalReverb = NULL;
} // destroy engine object, and invalidate all associated interfaces
if (engineObject != NULL) {
(*engineObject)->Destroy(engineObject);
engineObject = NULL;
engineEngine = NULL;
} }
参考文章
http://blog.csdn.net/u013898698/article/details/72822595
http://blog.csdn.net/ywl5320/article/details/78503768
Android 音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停和调整音量(附源码下载)的更多相关文章
- Android中Canvas绘图基础详解(附源码下载) (转)
Android中Canvas绘图基础详解(附源码下载) 原文链接 http://blog.csdn.net/iispring/article/details/49770651 AndroidCa ...
- Android 音视频深入 十一 FFmpeg和AudioTrack播放声音(附源码下载)
项目地址,求starhttps://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpeg%E6%92%AD%E6%94%BE%E ...
- Android开发学习之路--MediaPlayer之简单音乐播放器初体验
很多时候我们都会用手机来播放音乐,播放视频,那么具体地要怎么实现呢,其实主要是MediaPlayer类来完成的.下面通过简单的例子来实现一首歌曲的播放吧.新建工程MediaPlayerStudy,这里 ...
- Android学习笔记_24_多媒体MediaPlayer对象之音乐播放器与SoundPool声音池
一.MediaPlayer对象常用方法介绍: MediaPlayer mediaPlayer = new MediaPlayer(); if (mediaPlayer.isPlaying()) { m ...
- HTML+纯JS制作音乐播放器
该篇文章会教你通过JavaScript制作一个简单的音乐播放器.包括播放.暂停.上一曲和下一曲. 阅读本文章你需要对HTML.CSS和Javascript有基本的了解. 话不多说,先上图. emmm. ...
- Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)
项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...
- Android 音视频深入 十八 FFmpeg播放视频,有声音(附源码下载)
项目地址https://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpegv%E6%92%AD%E6%94%BE%E8%A7% ...
- Android 音视频深入 二十 FFmpeg视频压缩(附源码下载)
项目源码https://github.com/979451341/FFmpegCompress 这个视频压缩是通过类似在mac终端上输入FFmpeg命令来完成,意思是我们需要在Android上达到能够 ...
- Android 音视频深入 十九 使用ijkplayer做个视频播放器(附源码下载)
项目地址https://github.com/979451341/Myijkplayer 前段时候我觉得FFmpeg做个视频播放器好难,虽然播放上没问题,但暂停还有通过拖动进度条来设置播放进度,这些都 ...
随机推荐
- python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告
1.环境准备: python3.6 requests xlrd openpyxl HTMLTestRunner_api 2.目前实现的功能: 封装requests请求方法 在excel填写接口请求参数 ...
- python列表常用内建方法
python列表常用内建方法: abc = ['a',1,3,'a'] #abc.pop(1) #删除索引1的值.结果['a', 3] #abc.append([123]) #结果:['a', 1, ...
- tp5 model controlle sql
model::::use think\Db 引用db库类 用于数据库之类use think\Model 引用模板use think\Cookie 引用传值 $rs=Db::name(‘表名’)-> ...
- 蓝桥杯近三年初赛题之二(16年b组)
1. 煤球数目 有一堆煤球,堆成三角棱锥形.具体:第一层放1个,第二层3个(排列成三角形),第三层6个(排列成三角形),第四层10个(排列成三角形),....如果一共有100层,共有多少个煤球? 请填 ...
- to_date
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'; 会话已更改. SQL> SELECT TO_DATE(' ...
- web前端学习历程--跨域问题
一.同源策略 一个页面的ajax只能获取这个页面相同源(协议.域名.端口号都必须相同)的数据. 二.jsonp方法 1.json和jsonp JSON(JavaScript Object Notati ...
- JavaWeb-----实现第一个Servlet程序
1.Servlet简介 Servlet是在服务器端运行的一个小程序,实际上一个Servlet就是一个Java类,并且可以通过“请求-响应”编程模型来访问的这个驻留在服务器内 存里的servl ...
- K-wolf Number (数位DP)
题意:求区间内有多少个数满足条件:任意相邻的k个数位都不相等. 思路:老套路 #include<bits/stdc++.h> using namespace std; typedef lo ...
- 浅谈react的初步试用
现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...
- go get Unknown SSL protocol error in connection to gopkg.in
OSX go get报错 go get Unknown SSL protocol error in connection to gopkg.in https://github.com/niemeyer ...