android音乐播放器暂停播放,Android万能音频播放器07--添加停止播放功能并释放内存...

1、释放所分配的内存

释放顺序:释放队列->释放OpenSL->释放Audio->释放FFmpeg

1.1、释放队列

JfQueue.cpp

void JfQueue::clearAVPacket() {

//有可能释放资源时线程还在加锁中

pthread_cond_signal(&condPacket);

pthread_mutex_lock(&mutexPacket);

while (!queuePacket.empty()){

//先出队再释放

AVPacket *packet = queuePacket.front();

queuePacket.pop();

av_packet_free(&packet);

av_free(packet);

packet = NULL;

}

pthread_mutex_unlock(&mutexPacket);

}

暂停播放:

void JfAudio::stop() {

if (pcmPlayerObject != NULL){

(*pcmPlayerPlay)->SetPlayState(pcmPlayerPlay, SL_PLAYSTATE_STOPPED);

}

}

1.2、释放OpenSL、Audio:

void JfAudio::release() {

stop();

if (queue != NULL){

delete(queue);

queue = NULL;

}

if (pcmPlayerObject != NULL){

(*pcmPlayerObject)->Destroy(pcmPlayerObject);

pcmPlayerObject = NULL;

pcmPlayerPlay = NULL;

pcmBufferQueue = NULL;

}

if (outputMixObject != NULL){

(*outputMixObject)->Destroy(outputMixObject);

outputMixObject = NULL;

outputMixEnvReb = NULL;

}

if (engineObject != NULL){

(*engineObject)->Destroy(engineObject);

engineObject = NULL;

engineEngine = NULL;

}

if (buffer != NULL){

free(buffer);

buffer = NULL;

}

if (pACodecCtx != NULL){

avcodec_close(pACodecCtx);

avcodec_free_context(&pACodecCtx);

pACodecCtx = NULL;

}

if (playStatus != NULL){

playStatus = NULL;

}

if (callJava != NULL){

callJava = NULL;

}

}

1.3、释放FFmpeg:

这个比较麻烦,可能网络初始化中,可能还有其他线程,所以设置线程超时回调:void JfFFmpeg::decodeAudioThread()

int avformat_callback(void *ctx){

JfFFmpeg *jfFFmpeg = (JfFFmpeg *)ctx;

if (jfFFmpeg->playStatus->exit){

return AVERROR_EOF;

}

return 0;

}

pAFmtCtx->interrupt_callback.callback = avformat_callback;

pAFmtCtx->interrupt_callback.opaque = this;

释放FFmpeg资源

void JfFFmpeg::release() {

if (playStatus->exit){

return;

}

//这里的代码会直接继续向下走,但是某些线程可能还在执行

//如果在解码线程执行过程中就给线程加锁,一直等待线程执行完然后

playStatus->exit = true;

pthread_mutex_lock(&init_mutex);

int sleepCount = 0;

while (!exit){

if (sleepCount > 1000){

exit = true;

}

if (LOG_DEBUG){

LOGD("WAIT FFMPEG EXIT %d",sleepCount);

}

sleepCount++;

av_usleep(1000 * 10);//10ms

}

if (audio != NULL){

audio->release();

delete(audio);

audio = NULL;

}

if (pAFmtCtx != NULL){

avformat_close_input(&pAFmtCtx);

avformat_free_context(pAFmtCtx);

pAFmtCtx = NULL;

}

if (playStatus != NULL){

playStatus = NULL;

}

if (callJava != NULL) {

callJava = NULL;

}

pthread_mutex_unlock(&init_mutex);

}

1.4、Java调用暂停

public void stop(){

//在C++层有一个while循环,可能会耗时较长

new Thread(new Runnable() {

@Override

public void run() {

n_stop();

}

}).start();

}

private native void n_stop();

extern "C"

JNIEXPORT void JNICALL

Java_com_example_myplayer_player_JfPlayer_n_1stop(JNIEnv *env, jobject instance) {

// TODO

if (ffmpeg != NULL){

ffmpeg->release();

delete(ffmpeg);

ffmpeg = NULL;

if (callJava != NULL){

delete(callJava);

callJava = NULL;

}

if (playStatus != NULL){

delete(playStatus);

playStatus = NULL;

}

}

}

2、处理异常情况

比如:数据流还在加载中,就停止播放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值