900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > android音乐播放器暂停播放 Android万能音频播放器07--添加停止播放功能并释放内存...

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

时间:2023-10-11 10:06:18

相关推荐

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、处理异常情况

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。