MediaPlayer_Analyze-1-framework

本文详细介绍了Android平台上的MediaPlayer类的使用,从初始化、设置数据源、准备播放、播放控制到释放资源的全过程。涵盖了Java层的关键接口和方法,包括MediaPlayer的构造、setDataSource、prepare、start、pause、stop、reset和release等。同时,提到了线程间通信和本地/网络资源的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MediaPlayer Analyze - Framework Java层

MediaPlayer的简单使用

// ------ 初始化
// 方法一
MediaPlayer mp = new MediaPlayer();
mp.setDataSource("/sdcard/test.mp3");
// mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");
mp.prepare();

// 方法二
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //这时就不用调用setDataSource 和 prepare 了

// ------ 播放/暂停/停止/释放
mp.start();
mp.pause();
mp.stop();
mp.release();

一 初始化

1.1 app java调用

// 方法一
MediaPlayer mp = new MediaPlayer();

// 方法二
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //这时就不用调用setDataSource了

1.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

public class MediaPlayer extends PlayerBase implements SubtitleController.Listener, VolumeAutomation, AudioRouting{

    public MediaPlayer() {
        super(new AudioAttributes.Builder().build(), AudioPlaybackConfiguration.PLAYER_TYPE_JAM_MEDIAPLAYER);

        // 线程间异步消息通信(用户不需要考虑互斥加锁的问题) looper,并创建 EventHandler
        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        mTimeProvider = new TimeProvider(this);
        mOpenSubtitleSources = new Vector<InputStream>();

        // 调用jni层接口
        native_setup(new WeakReference<MediaPlayer>(this));

        baseRegisterPlayer();
    }
}

有 looper 就有 handler:

frameworks\base\media\java\android\media\MediaPlayer.java

    private class EventHandler extends Handler
    {
        private MediaPlayer mMediaPlayer;

        public EventHandler(MediaPlayer mp, Looper looper) {
            super(looper);
            mMediaPlayer = mp;
        }

        @Override
        public void handleMessage(Message msg) {
        ...
        }
    }

有 native 方法就有:

frameworks\base\media\java\android\media\MediaPlayer.java

    static {
        System.loadLibrary("media_jni");
        native_init();
    }

二 设置source

2.1 app调用

// 方法一
mp.setDataSource("/sdcard/test.mp3");
// mp.setDataSource("http://www.citynorth.cn/music/confucius.mp3");

// 方法二
MediaPlayer mp = MediaPlayer.create(this, R.raw.test); //这时就不用调用setDataSource 和 prepare了

2.2 framework-java层接口

最后都会调用到:

frameworks\base\media\java\android\media\MediaPlayer.java

    private void setDataSource(String path, String[] keys, String[] values, List<HttpCookie> cookies)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        final Uri uri = Uri.parse(path);
        // 查找patch对应的方案
        final String scheme = uri.getScheme();
        if ("file".equals(scheme)) { // 本地流
            path = uri.getPath();
        } else if (scheme != null) { // 非本地流,如网络片源
            // handle non-file sources
            nativeSetDataSource( // 非本地流调用
                MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),
                path,
                keys,
                values);
            return;
        }

        final File file = new File(path);
        try (FileInputStream is = new FileInputStream(file)) {
            setDataSource(is.getFD());
        }
    }
    private native void nativeSetDataSource(IBinder httpServiceBinder, String path, String[] keys, String[] values)
        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
    
    //  本地流调用
    public void setDataSource(FileDescriptor fd, long offset, long length)
            throws IOException, IllegalArgumentException, IllegalStateException {
        _setDataSource(fd, offset, length);
    }
    private native void _setDataSource(FileDescriptor fd, long offset, long length)
            throws IOException, IllegalArgumentException, IllegalStateException;

三 准备prepare

3.1 app调用

mp.prepare();

3.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

    public void prepare() throws IOException, IllegalStateException {
        _prepare();
        scanInternalSubtitleTracks();

        // DrmInfo, if any, has been resolved by now.
        synchronized (mDrmLock) {
            mDrmInfoResolved = true;
        }
    }
    private native void _prepare() throws IOException, IllegalStateException;

四 开始/恢复播放

4.1 app调用

mp.start();

4.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

    // TODO: 暂时没找到怎样保存播放进度,resume如何恢复
    public void start() throws IllegalStateException {
        final int delay = getStartDelayMs();
        if (delay == 0) {
            startImpl();
        } else {
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(delay);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    baseSetStartDelayMs(0);
                    try {
                        startImpl();
                    } catch (IllegalStateException e) {
                    }
                }
            }.start();
        }
    }

    private void startImpl() {
        baseStart(); // 更新状态信息 PlayerBase.java
        stayAwake(true); // 如果有显示,则保持亮屏
        _start();
    }
    private native void _start() throws IllegalStateException;

五 暂停播放

5.1 app调用

mp.pause();

5.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

    public void pause() throws IllegalStateException {
        stayAwake(false); // 如果有显示,关闭保持亮屏
        _pause();
        basePause(); // 更新状态信息 PlayerBase.java
    }
    private native void _pause() throws IllegalStateException;

六 停止播放

6.1 app调用

mp.stop();

6.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

    public void stop() throws IllegalStateException {
        stayAwake(false); // 如果有显示,关闭保持亮屏
        _stop();
        baseStop(); // 更新状态信息 PlayerBase.java
    }
    private native void _stop() throws IllegalStateException;

七 重置

7.1 app调用

mp.reset();

7.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

    public void reset() {
        mSelectedSubtitleTrackIndex = -1;
        synchronized(mOpenSubtitleSources) {
            for (final InputStream is: mOpenSubtitleSources) {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
            mOpenSubtitleSources.clear();
        }
        if (mSubtitleController != null) {
            mSubtitleController.reset();
        }
        synchronized (mTimeProviderLock) {
            if (mTimeProvider != null) {
                mTimeProvider.close();
                mTimeProvider = null;
            }
        }

        stayAwake(false);
        _reset();
        // make sure none of the listeners get called anymore
        if (mEventHandler != null) {
            mEventHandler.removeCallbacksAndMessages(null);
        }

        synchronized (mIndexTrackPairs) {
            mIndexTrackPairs.clear();
            mInbandTrackIndices.clear();
        };

        resetDrmState();
    }
    private native void _reset();

八 释放

8.1 app调用

mp.release();

8.2 framework-java层接口

frameworks\base\media\java\android\media\MediaPlayer.java

    public void release() {
        baseRelease();
        stayAwake(false);
        updateSurfaceScreenOn();
        mOnPreparedListener = null;
        mOnBufferingUpdateListener = null;
        mOnCompletionListener = null;
        mOnSeekCompleteListener = null;
        mOnErrorListener = null;
        mOnInfoListener = null;
        mOnVideoSizeChangedListener = null;
        mOnTimedTextListener = null;
        synchronized (mTimeProviderLock) {
            if (mTimeProvider != null) {
                mTimeProvider.close();
                mTimeProvider = null;
            }
        }
        synchronized(this) {
            mSubtitleDataListenerDisabled = false;
            mExtSubtitleDataListener = null;
            mExtSubtitleDataHandler = null;
            mOnMediaTimeDiscontinuityListener = null;
            mOnMediaTimeDiscontinuityHandler = null;
        }

        // Modular DRM clean up
        mOnDrmConfigHelper = null;
        mOnDrmInfoHandlerDelegate = null;
        mOnDrmPreparedHandlerDelegate = null;
        resetDrmState();

        _release();
    }
    private native void _release();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值