IjkPlayer 播放音频、完整代码;

说明:播放器核心采用IjkPlayer(bilibili开源库)、so库采用GsyVideoPlayer(IjkPlayer so 默认不支持https 格式!)

Demo:地址 https://download.csdn.net/download/BirdEatBug/19363714 无需积分 demo 需要关注 MediaPlayerActivity与MediaService两个类即可; 

播放器代码:


package com.kuaige.player.player;

import android.media.AudioManager;

import java.io.IOException;

import tv.danmaku.ijk.media.player.IjkMediaPlayer;

public class IjkAudioPlayer {

    private IjkMediaPlayer ijkMediaPlayer;

    public IjkMediaPlayer getPlayer() {
        return ijkMediaPlayer;
    }

    public void init() {
        if (ijkMediaPlayer == null) {
            ijkMediaPlayer = new IjkMediaPlayer();
            ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER,"soundtouch",0);
            ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"analyzemaxduration",50L);

          /*  ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"analyzeduration",1);
            ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"probesize",1024*10);*/
        }
        ijkMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    }

    public void setPathAndPrepare(String uri) {
        try {
            ijkMediaPlayer.setDataSource(uri);
            ijkMediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start() {
        if (ijkMediaPlayer != null) {
            ijkMediaPlayer.start();
        }
    }

    public void pause(){
        if (ijkMediaPlayer != null) {
            ijkMediaPlayer.pause();
        }
    }

    public void stop(){
        if (ijkMediaPlayer != null) {
            ijkMediaPlayer.stop();
        }
    }

    /**
     * 耗时
     */
    public void reset(){
        if (ijkMediaPlayer != null) {
            ijkMediaPlayer.reset();
        }
    }

    public void release() {
        if (ijkMediaPlayer != null) {
            ijkMediaPlayer.reset();
            ijkMediaPlayer.release();
            ijkMediaPlayer = null;
        }
    }

}

Service代码:


package com.kuaige.player.player;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.kuaige.player.R;
import com.kuaige.player.RadioAudioEvent;
import com.kuaige.player.utils.AudioFocusManager;

import org.greenrobot.eventbus.EventBus;

import tv.danmaku.ijk.media.player.IMediaPlayer;

public class MediaService extends Service implements IMediaPlayer.OnErrorListener, IMediaPlayer.OnPreparedListener {

    //ijk播放器
    private IjkAudioPlayer ijkAudioPlayer;

    private AudioFocusManager audioFocusManager = new AudioFocusManager();

    private boolean isPrepared;

    private boolean isStop;

    private boolean isPause;

    //是否播放过音乐、防止多次启动时setPathAndPrepare 异常(无法捕获)
    private boolean isInit;

    private static final String PLAY_URI = "play_uri";
    private static final String PLAY = "play";
    private static final String CONTINUE_PLAY = "continue_play";
    private static final String PAUSE = "pause";
    private static final String STOP = "stop";

    public static final String STOP_PLAY_SERVICE = "stop_play_service";

    public static final int RELEASE = 101;

    //记录播放uri
    private String oldUri = "";

    private Handler handler = new Handler();

    public static void startPlay(Context context, String uri) {
        context.startService(new Intent(context, MediaService.class).putExtra(PLAY_URI, uri).setAction(PLAY));
    }

    //继续播放、若已发生暂停
    public static void continuePlay(Context context) {
        context.startService(new Intent(context, MediaService.class).setAction(CONTINUE_PLAY));
    }


    public static void pausePlay(Context context) {
        context.startService(new Intent(context, MediaService.class).setAction(PAUSE));
    }

    public static void stopPlay(Context context) {
        context.startService(new Intent(context, MediaService.class).setAction(STOP));
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (ijkAudioPlayer == null) {
            ijkAudioPlayer = new IjkAudioPlayer();
            ijkAudioPlayer.init();
            ijkAudioPlayer.getPlayer().setOnErrorListener(this);
            ijkAudioPlayer.getPlayer().setOnPreparedListener(this);
        }
        initAudioListener();
        //常驻通知栏
        createMusicNotification(this);
    }

    private void initAudioListener() {
      /*  //请求语音播放焦点
        int requestCode = audioFocusManager.requestTheAudioFocus(new AudioFocusManager.AudioListener() {
            @Override
            public void start() {
                Log.d("----------tag", "start");
            }

            @Override
            public void pause() {
                Log.d("----------tag", "pause");
            }
        }, this);
        if(requestCode == AudioManager.AUDIOFOCUS_REQUEST_GRANTED){
//            playVoice();//播放音频的方法
            Log.d("----------tag", "AUDIOFOCUS_REQUEST_GRANTED");
        }*/
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null && intent.getAction() != null) {
            switch (intent.getAction()) {
                case CONTINUE_PLAY:
                    if (!TextUtils.isEmpty(oldUri)) {
                        if (isPrepared && isPause) {
                            ijkAudioPlayer.start();
                            isPause = false;
                        }
                    }
                    break;
                case PLAY:
                    String uri = intent.getStringExtra(PLAY_URI);
                    boolean sameUri = oldUri.equals(uri);
                    oldUri = uri;
                    //是否是暂停
                    if (isPrepared && isPause && sameUri) {
                        ijkAudioPlayer.start();
                        isPause = false;
                        EventBus.getDefault().post(new RadioAudioEvent(true));
                        //当停止播放时
                    } else if (isStop || ijkAudioPlayer.getPlayer().isPlaying() || !sameUri) {
                        ijkAudioPlayer.stop();
                        ijkAudioPlayer.reset();
                        ijkAudioPlayer.setPathAndPrepare(uri);
                    } else {
                        if (!isInit) {
                            ijkAudioPlayer.setPathAndPrepare(uri);
                        }
                    }
//                    mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
                    break;
                case PAUSE:
                    if (ijkAudioPlayer.getPlayer().isPlaying()) {
                        ijkAudioPlayer.pause();
                        isPause = true;
                    }
                    break;
                case STOP:
                    if (ijkAudioPlayer.getPlayer().isPlaying()) {
                        ijkAudioPlayer.stop();
                        isPrepared = false;
                        isStop = true;
                    }
                    break;
                case STOP_PLAY_SERVICE:
                    stopSelf();
                    break;
            }
        }
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        ijkAudioPlayer.stop();
        ijkAudioPlayer.release();
        isPrepared = false;
    }

    @Override
    public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
        isPrepared = false;
        isStop = true;
        Toast.makeText(this, "出错了、请重试!", Toast.LENGTH_SHORT).show();
        EventBus.getDefault().post(new RadioAudioEvent(true));
        return false;
    }

    @Override
    public void onPrepared(IMediaPlayer iMediaPlayer) {
        isInit = true;
        isPrepared = true;
        isStop = false;
        iMediaPlayer.start();
        isPause = false;
        //通知 主model
        EventBus.getDefault().post(new RadioAudioEvent(true));
    }

    public void createMusicNotification(Context context) {

        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("qiqile", "齐齐乐渠道",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "qiqile");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setOngoing(true);//代表是常驻的,主要是配合服务

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notify_custom);
        //暂停或者重新播放
        Intent stopIntent = new Intent(context, MediaService.class);
        stopIntent.setAction(STOP_PLAY_SERVICE);

        PendingIntent startOrPauseP = PendingIntent.getService(context, MediaService.RELEASE, stopIntent, 0);
        remoteViews.setOnClickPendingIntent(R.id.ivStop, startOrPauseP);

        builder.setContent(remoteViews);
        Notification notification = builder.build();
        startForeground(0x11, notification);
    }

}

备注:状态控制有些啰嗦、可自行修改!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值