SurfaceView surfaceView;    SurfaceHolder holder;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        surfaceView = findViewById(R.id.surfaceView);        holder = surfaceView.getHolder();        /**         * 视频输入         */        VideoThread videoThread = new VideoThread(holder);        videoThread.start();        /**         * 音频输入         */       SecondThread secondThread = new SecondThread();       secondThread.start();    }}class VideoThread extends Thread{    private SurfaceHolder holder;    public VideoThread(SurfaceHolder holder){        this.holder = holder;    }    @Override    public void run() {        try {            final MediaExtractor extractor = new MediaExtractor();            //设置视频地址            String path = Environment.getExternalStorageDirectory().getPath() + "/h265.mp4";            extractor.setDataSource(path);            extractor.seekTo(5000, SEEK_TO_NEXT_SYNC);            //Count the number of tracks found in the data source.信道总数一般为2 一个视频一个音频            int numTrack = extractor.getTrackCount();            for (int i = 0; i < numTrack; i++) {                //Get the track format at the specified index                final MediaFormat format = extractor.getTrackFormat(i);                //得到数据信息 1.video/avc  2.audio/mp4a-latm                String mimetype = format.getString(MediaFormat.KEY_MIME);                Log.d("tag", mimetype);                if (mimetype.startsWith("video")) {                    //选择频道                    extractor.selectTrack(i);                    final MediaCodec mediaCodec = MediaCodec.createDecoderByType(mimetype);//                    mPlayer = new AudioPlayer(format.getInteger(MediaFormat.KEY_SAMPLE_RATE), AudioFormat//                            .CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);//                    mPlayer.init();                    holder.addCallback(new SurfaceHolder.Callback() {                        @Override                        public void surfaceCreated(SurfaceHolder holder) {                            mediaCodec.configure(format, holder.getSurface(), null, 0);//                                    outputFormat = format;                            mediaCodec.start();                        }                        @Override                        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {                        }                        @Override                        public void surfaceDestroyed(SurfaceHolder holder) {                        }                    });                    mediaCodec.setCallback(new MediaCodec.Callback() {                        @Override                        public void onInputBufferAvailable(MediaCodec codec, int index) {                            ByteBuffer inputBuffer = codec.getInputBuffer(index);                            inputBuffer.clear();                            int readlen = extractor.readSampleData(inputBuffer, 0);                            Log.d("tag", "视频输入" + inputBuffer.toString());                            codec.queueInputBuffer(index, 0, readlen, 0, 0);                            extractor.advance();//Advance to the next sample.进入下一帧 刷新                        }                        @Override                        public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {                            Log.d("tag", "onOutputBufferAvailable:" + info.size);                            ByteBuffer outputBuffer = codec.getOutputBuffer(index);                            MediaFormat outformat = codec.getOutputFormat();                            if (outputBuffer != null && info.size > 0) {                                byte[] buffer = new byte[outputBuffer.remaining()];                                outputBuffer.get(buffer);//                                 mPlayer.play(buffer,0,info.size);                                Log.d("tag", "Offer to queue failed, queue in full state");                            }                            codec.releaseOutputBuffer(index, true);                        }                        @Override                        public void onError(MediaCodec codec, MediaCodec.CodecException e) {                            Log.d("tag", "onError:" + e.getDiagnosticInfo());                        }                        @Override                        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {                            Log.d("tag", "onOutputFormatChanged:");//                                    outputFormat = format;                        }                    });                }            }        } catch (IOException e) {            e.printStackTrace();        }    }}class SecondThread extends Thread{    AudioPlayer mPlayer;    @Override    public void run() {        try {            final MediaExtractor extractor = new MediaExtractor();            //设置视频地址            String path = Environment.getExternalStorageDirectory().getPath() + "/h265.mp4";            extractor.setDataSource(path);            extractor.seekTo(5000, SEEK_TO_NEXT_SYNC);            //Count the number of tracks found in the data source.信道总数一般为2 一个视频一个音频            int numTrack = extractor.getTrackCount();            for (int i = 0; i < numTrack; i++) {                //Get the track format at the specified index                final MediaFormat format = extractor.getTrackFormat(i);                //得到数据信息 1.video/avc  2.audio/mp4a-latm                String mimetype = format.getString(MediaFormat.KEY_MIME);                Log.d("tag", mimetype);                if (mimetype.startsWith("audio")) {                    //选择频道                    extractor.selectTrack(i);                    final MediaCodec mediaCodec = MediaCodec.createDecoderByType(mimetype);                    mPlayer = new AudioPlayer(format.getInteger(MediaFormat.KEY_SAMPLE_RATE), AudioFormat                            .CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);                    mPlayer.init();                    mediaCodec.setCallback(new MediaCodec.Callback() {                        @Override                        public void onInputBufferAvailable(MediaCodec codec, int index) {                            ByteBuffer inputBuffer = codec.getInputBuffer(index);                            inputBuffer.clear();                            int readlen = extractor.readSampleData(inputBuffer, 0);                            Log.d("tag", "音频输入" + inputBuffer.toString());                            codec.queueInputBuffer(index, 0, readlen, 0, 0);                            extractor.advance();//Advance to the next sample.进入下一帧 刷新                        }                        @Override                        public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {                            Log.d("tag", "onOutputBufferAvailable:" + info.size);                            ByteBuffer outputBuffer = codec.getOutputBuffer(index);                            MediaFormat outformat = codec.getOutputFormat();                            if (outputBuffer != null && info.size > 0) {                                byte[] buffer = new byte[outputBuffer.remaining()];                                outputBuffer.get(buffer);                                mPlayer.play(buffer, 0, info.size);                                Log.d("tag", "Offer to queue failed, queue in full state");                            }                            codec.releaseOutputBuffer(index, true);                        }                        @Override                        public void onError(MediaCodec codec, MediaCodec.CodecException e) {                            Log.d("tag", "onError:" + e.getDiagnosticInfo());                        }                        @Override                        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {                            Log.d("tag", "onOutputFormatChanged:");//                                    outputFormat = format;                        }                    });                    mediaCodec.configure(format, null, null, 0);//                            outputFormat = format;                    mediaCodec.start();                }            }        } catch (IOException e) {            e.printStackTrace();        }    }public class AudioPlayer {    private int mFrequency;// 采样率    private int mChannel;// 声道    private int mSampBit;// 采样精度    private AudioTrack mAudioTrack;    public AudioPlayer(int frequency, int channel, int sampbit) {        this.mFrequency = frequency;        this.mChannel = channel;        this.mSampBit = sampbit;    }    /**     * 初始化     */    public void init() {        if (mAudioTrack != null) {            release();        }        // 获得构建对象的最小缓冲区大小        int minBufSize = AudioTrack.getMinBufferSize(mFrequency, mChannel, mSampBit);        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,                mFrequency, mChannel, mSampBit, minBufSize, AudioTrack.MODE_STREAM);        mAudioTrack.play();    }    /**     * 释放资源     */    private void release() {        if (mAudioTrack != null) {            mAudioTrack.stop();            mAudioTrack.release();        }    }    /**     * 将解码后的pcm数据写入audioTrack播放     *     * @param data   数据     * @param offset 偏移     * @param length 需要播放的长度     */    public void play(byte[] data, int offset, int length) {        if (data == null || data.length == 0) {            return;        }        try {            mAudioTrack.write(data, offset, length);        } catch (Exception e) {            e.printStackTrace();        }    }}

 

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. SharedPreferences保存少量的数据
  3. 【黑马Android】(03)学生管理系统/动态刷新界面
  4. android项目中单实例数据库类
  5. SharedPreferences 数据存储
  6. Android(安卓)RSA 公钥加密、解密
  7. Android下建立数据库
  8. 了解Context
  9. Android缓存清理

随机推荐

  1. 从网瘾少年逆袭拿到微软 、字节等offer(上
  2. 单链表字符串判断回文
  3. 从网瘾少年逆袭拿到微软 、字节等offer(下
  4. 高新技术企业优惠政策,及认定要求
  5. 堆实战(动态数据流求top k大元素,动态数
  6. 单链表反转
  7. php守护进程创建和简要分析
  8. master-worker常驻型程序代码修改哪些需
  9. 归并排序
  10. 你要的 Spark AI Summit 2020 PPT 我已经