微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android 音视频数据播放封装类

音频

public class CAudioTrack {

    private final int mFrequency;
    private final int mChannel;
    private final int mAudioFormat;
    private AudioTrack mAudioTrack;

    public CAudioTrack(int frequency, int channel, int audioFormat) {
        this.mFrequency = frequency;
        this.mChannel = channel;
        this.mAudioFormat = audioFormat;
    }

    /**
     * 初始化
     */
    public void init() {
        if (mAudioTrack != null) {
            release();
        }
        // 获得构建对象的最小缓冲区大小
        int minBufSize = 2 * getMinBufferSize();
        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                mFrequency, mChannel, mAudioFormat, minBufSize, AudioTrack.MODE_STREAM);
        mAudioTrack.play();
    }

    /**
     * 释放资源
     */
    public void release() {
        if (mAudioTrack != null) {
            mAudioTrack.stop();
            mAudioTrack.release();
        }
    }

    private int getMinBufferSize() {
        return AudioTrack.getMinBufferSize(mFrequency, mChannel, mAudioFormat);
    }


    public void write(byte[] data) {
        if (mAudioTrack != null) {
            mAudioTrack.write(data, 0, data.length);
        }
    }

}

视频

public class CVideoPlayer {

    private volatile MediaCodec mDecoder;
    private volatile boolean mDecodeStarted = false;
    final private reentrantlock mPlayerLock = new reentrantlock();

    /**
     * 打开视频播放器
     *
     * @param width   视频宽度
     * @param height  视频高度
     * @param surface 播放视频的surface
     * @return 是否开启成功
     */
    public boolean open(int width, int height, Surface surface) {
        try {
            mPlayerLock.lock();
            Logger.d("CVideoPlayer open, mDecodeStarted is " + mDecodeStarted + " width is " + width + " ; height is " + height);
            if (mDecodeStarted) {
                //已经open无需重复操作
                return true;
            }

            //电话终端会出现解码器释放失败的问题,影响下一次的创建和播放
            //这里如果不为空,说明上一次释放出现异常,再手动调用下close,能保证此次正常
            if (mDecoder != null) {
                close();
            }

            MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height);
            mDecoder = MediaCodec.createDecoderByType("video/avc");
            mDecoder.configure(format, surface, null, 0);
            mDecoder.start();

            mDecodeStarted = true;
            Logger.d("open CVideoPlayer success");
        } catch (Exception e) {
            Logger.e("open CVideoPlayer exception: " + e.getMessage());
            mDecodeStarted = false;
            mDecoder = null;
            return false;
        } finally {
            mPlayerLock.unlock();
        }
        return true;
    }

    /**
     * 关闭视频播放器,释放资源
     */
    public void close() {
        try {
            mPlayerLock.lock();
            Logger.d("close CVideoPlayer begin");
            mDecodeStarted = false;
            if (mDecoder != null) {
                mDecoder.stop();
                mDecoder.release();
                mDecoder = null;
            }
            Logger.d("close CVideoPlayer end");
        } catch (Exception e) {
            Logger.e("close CVideoPlayer error : " + e.getMessage());
        } finally {
            mPlayerLock.unlock();
        }
    }

    /**
     * 播放视频流数据
     * @param data ES流
     * @param length 数据长度
     * @param pts presentation time
     */
    public void play(byte[] data, int length, int pts) {
        try {
            mPlayerLock.lock();
            if (!mDecodeStarted || mDecoder == null) {
                Logger.e("decoder is null, mDecodeStarted is " + mDecodeStarted + "; mDecoder is " + mDecoder);
                return;
            }
            onFrame(data, length, pts);
        } catch (Exception e) {
            Logger.e("CVideoPlayer play exception: " + e.getMessage());
        } finally {
            mPlayerLock.unlock();
        }
    }

    public void onFrame(byte[] buf, int length, long pts) {
        // Get input buffer index
        int inputBufferIndex = mDecoder.dequeueInputBuffer(100);

        if (inputBufferIndex >= 0) {
            //ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
            ByteBuffer inputBuffer;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                inputBuffer = mDecoder.getInputBuffer(inputBufferIndex);
            } else {
                inputBuffer = mDecoder.getInputBuffers()[inputBufferIndex];
            }
            inputBuffer.clear();
            inputBuffer.put(buf, 0, length);
            mDecoder.queueInputBuffer(inputBufferIndex, 0, length, pts, 0);
        } else {
            return;
        }

        // Get output buffer index
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mDecoder.dequeueOutputBuffer(bufferInfo, 100);
        while (outputBufferIndex >= 0) {
            mDecoder.releaSEOutputBuffer(outputBufferIndex, true);
            outputBufferIndex = mDecoder.dequeueOutputBuffer(bufferInfo, 0);
        }
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐