当前位置: 首页 > news >正文

电脑怎么打不开建设银行网站电商seo

电脑怎么打不开建设银行网站,电商seo,vue做的博客网站,开网店视频教程一.简述 最近疏于写文,忙里抽闲写一篇关于MediaCodec使用的博文,对上一篇MediaCodec的理论讲解进行落地实现。 使用MediaCodec开发一个简易VideoPlayer,对一个视频进行解码播放的过程并不复杂。 实现过程采用的是MediaCodec的同步方式 废…

一.简述

最近疏于写文,忙里抽闲写一篇关于MediaCodec使用的博文,对上一篇MediaCodec的理论讲解进行落地实现。

使用MediaCodec开发一个简易VideoPlayer,对一个视频进行解码播放的过程并不复杂。

实现过程采用的是MediaCodec的同步方式

废话不多说了,先上图阐明流程,再上代码具体实现。

二.MediaCodec解码流程

三.代码实现

简易VideoPlayer的代码文件并不多,一共也只有四个文件:
MainActivity.java:UI显示,Surface监听,视频和音频解码线程控制
VideoDecodeThread.java:视频解码线程
AudioDecodeThread.java:音频解码线程
ICodecInterface.java:用于视频/音频解码线程和MainActivity数据通讯

上代码:

res/layout/activity_main.xml
layout里不用添加什么UI控件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"></androidx.constraintlayout.widget.ConstraintLayout>

src\main\java\com\android\mediacodec\MainActivity.java

package com.android.mediacodec;import android.app.Activity;import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;/*** MediaCodec VideoPlayer Example** @author Shawn*/
public class MainActivity extends Activity implements SurfaceHolder.Callback, ICodecInterface {private static final String TAG = "MainActivity";//路径目前是写死的,需要在手机根目录下先拷贝一个名字为mediatest的mp4视频文件private static final String FILE_PATH = Environment.getExternalStorageDirectory() + "/mediatest.mp4";private VideoDecodeThread mVideoDecodeThread;private AudioDecodeThread mAudioDecodeThread;private int mVideoWidth, mVideoHeight;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SurfaceView surfaceView = new SurfaceView(this);surfaceView.getHolder().addCallback(this);setContentView(surfaceView);}@Overridepublic void changeVideoSize(int width, int height) {Log.v(TAG, "VideosizeCallBack()   width:" + width + " x " + "height:" + height);mVideoWidth = width;mVideoHeight = height;}//改变视频的尺寸自适应。public void changeVideoSize() {//do nothing frist}@Overridepublic void surfaceCreated(SurfaceHolder holder) {//do nothing frist}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {if (mVideoDecodeThread == null) {mVideoDecodeThread = new VideoDecodeThread(holder.getSurface(), FILE_PATH);mVideoDecodeThread.setPlayStateListener(this);mVideoDecodeThread.start();}if (mAudioDecodeThread == null) {mAudioDecodeThread = new AudioDecodeThread(FILE_PATH);mAudioDecodeThread.start();}}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (mVideoDecodeThread != null) {mVideoDecodeThread.interrupt();}if (mAudioDecodeThread != null) {mAudioDecodeThread.interrupt();}}/*** 关闭线程*/public void destroy() {if (mVideoDecodeThread != null) {mVideoDecodeThread.close();}if (mAudioDecodeThread != null) {mAudioDecodeThread.close();}}
}

src\main\java\com\android\mediacodec\VideoDecodeThread.java 

package com.android.mediacodec;import java.io.IOException;
import java.nio.ByteBuffer;import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;
import android.view.Surface;public class VideoDecodeThread extends Thread {private static final String TAG = "VideoDecoderThread";private MediaExtractor mVideoExtractor;private MediaCodec mVideoDecoder;private Surface mSurface;private String mFilePath;private ICodecInterface mListener;private static final long TIMEOUT_US = 10000;private static final String VIDEO = "video/";public VideoDecodeThread(Surface surface, String filePath) {mSurface = surface;mFilePath = filePath;}/*** 设置回调* @param listener*/public void setPlayStateListener(ICodecInterface listener) {mListener = listener;}@Overridepublic void run() {mVideoExtractor = new MediaExtractor();try {mVideoExtractor.setDataSource(mFilePath);} catch (IOException e) {e.printStackTrace();}//获取视频所在轨道for (int i = 0; i < mVideoExtractor.getTrackCount(); i++) {MediaFormat mediaformat = mVideoExtractor.getTrackFormat(i);//Log.d(TAG, "getTrackCount: " + mExtractor.getTrackCount());String mime = mediaformat.getString(MediaFormat.KEY_MIME);if (mime.startsWith(VIDEO)) {MediaFormat format = mVideoExtractor.getTrackFormat(i);Log.d(TAG, "format : " + format);int width = mediaformat.getInteger(MediaFormat.KEY_WIDTH);int height = mediaformat.getInteger(MediaFormat.KEY_HEIGHT);float time = mediaformat.getLong(MediaFormat.KEY_DURATION) / 1000000;mListener.changeVideoSize(width, height);mVideoExtractor.selectTrack(i);try {mVideoDecoder = MediaCodec.createDecoderByType(mime);mVideoDecoder.configure(format, mSurface, null, 0 /* Decoder */);} catch (IOException e) {Log.e(TAG, "codec '" + mime + "' failed configuration. " + e);return;}}}if (mVideoDecoder == null) {Log.e(TAG, "video decoder is unexpectedly null");return;}mVideoDecoder.start();BufferInfo videoBufferInfo = new BufferInfo();ByteBuffer[] inputBuffers = mVideoDecoder.getInputBuffers();//mVideoDecoder.getOutputBuffers();boolean eosReceived = false;long startTime = System.currentTimeMillis();while (!Thread.interrupted()) {//将资源传递到解码器if (!eosReceived) {int inputIndex = mVideoDecoder.dequeueInputBuffer(TIMEOUT_US);if (inputIndex >= 0) {// fill inputBuffers[inputBufferIndex] with valid dataByteBuffer inputBuffer = inputBuffers[inputIndex];int sampleSize = mVideoExtractor.readSampleData(inputBuffer, 0);if (sampleSize > 0) {mVideoDecoder.queueInputBuffer(inputIndex, 0, sampleSize, mVideoExtractor.getSampleTime(), 0);mVideoExtractor.advance();} else {Log.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");mVideoDecoder.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);eosReceived = true;}}}int outIndex = mVideoDecoder.dequeueOutputBuffer(videoBufferInfo, TIMEOUT_US);switch (outIndex) {//当buffer变化时,必须重新指向新的buffercase MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED");//mVideoDecoder.getOutputBuffers();break;//当Buffer的封装格式发生变化的时候,需重新指向新的buffer格式case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:Log.d(TAG, "INFO_OUTPUT_FORMAT_CHANGED format : " + mVideoDecoder.getOutputFormat());break;case MediaCodec.INFO_TRY_AGAIN_LATER:Log.d(TAG, "INFO_TRY_AGAIN_LATER");break;default:while ((videoBufferInfo.presentationTimeUs / 1000) > (System.currentTimeMillis() - startTime)) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();break;}}mVideoDecoder.releaseOutputBuffer(outIndex, true /* Surface init */);break;}// All decoded frames have been rendered, we can stop playing nowif ((videoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {Log.d(TAG, "OutputBuffer BUFFER_FLAG_END_OF_STREAM");break;}}mVideoDecoder.stop();mVideoDecoder.release();mVideoExtractor.release();}public void close() {//do nothing frist}
}

src\main\java\com\android\mediacodec\AudioDecodeThread.java
解码视频的同时也需要解码音频,要不然播放就会没有声音
要注意一点的是音频解码与视频的时间同步,否则就会出现声音和画面对不上的现象

package com.android.mediacodec;import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;import java.io.IOException;
import java.nio.ByteBuffer;public class AudioDecodeThread extends Thread {private static final String TAG = "AudioDecodeThread";MediaExtractor mAudioExtractor = new MediaExtractor();MediaCodec mAudioDecoder = null;private int mInputBufferSize;private AudioTrack mAudioTrack;private String mFilePath;private static final String AUDIO = "audio/";private static final long TIMEOUT_US = 10000;//private boolean isAudioEOS = false;public AudioDecodeThread(String filePath) {mFilePath = filePath;}@Overridepublic void run() {try {mAudioExtractor.setDataSource(mFilePath);} catch (IOException e) {e.printStackTrace();}for (int i = 0; i < mAudioExtractor.getTrackCount(); i++) {MediaFormat mediaFormat = mAudioExtractor.getTrackFormat(i);String mime = mediaFormat.getString(MediaFormat.KEY_MIME);if (mime.startsWith(AUDIO)) {//设置音轨mAudioExtractor.selectTrack(i);int audioChannels = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);int audioSampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);int minBufferSize = AudioTrack.getMinBufferSize(audioSampleRate,(audioChannels == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO),AudioFormat.ENCODING_PCM_16BIT);int maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);mInputBufferSize = minBufferSize > 0 ? minBufferSize * 4 : maxInputSize;int frameSizeInBytes = audioChannels * 2;mInputBufferSize = (mInputBufferSize / frameSizeInBytes) * frameSizeInBytes;mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,audioSampleRate,(audioChannels == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO),AudioFormat.ENCODING_PCM_16BIT,mInputBufferSize,AudioTrack.MODE_STREAM);mAudioTrack.play();try {mAudioDecoder = MediaCodec.createDecoderByType(mime);mAudioDecoder.configure(mediaFormat, null, null, 0);} catch (IOException e) {e.printStackTrace();}break;}}if (mAudioDecoder == null) {Log.e(TAG, "audio decoder is unexpectedly null");return;}mAudioDecoder.start();final ByteBuffer[] buffers = mAudioDecoder.getOutputBuffers();int sz = buffers[0].capacity();if (sz <= 0) {sz = mInputBufferSize;}byte[] mAudioOutTempBuf = new byte[sz];BufferInfo audioBufferInfo = new BufferInfo();ByteBuffer[] inputBuffers = mAudioDecoder.getInputBuffers();ByteBuffer[] outputBuffers = mAudioDecoder.getOutputBuffers();long startMs = System.currentTimeMillis();boolean eosReceived = false;while (!Thread.interrupted()) {if (!eosReceived) {int inputIndex = mAudioDecoder.dequeueInputBuffer(TIMEOUT_US);if (inputIndex >= 0) {// fill inputBuffers[inputBufferIndex] with valid dataByteBuffer inputBuffer = inputBuffers[inputIndex];int sampleSize = mAudioExtractor.readSampleData(inputBuffer, 0);if (sampleSize > 0) {mAudioDecoder.queueInputBuffer(inputIndex, 0, sampleSize, mAudioExtractor.getSampleTime(), 0);mAudioExtractor.advance();} else {Log.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");mAudioDecoder.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);eosReceived = true;}}}// 获取解码后的数据int outputBufferIndex = mAudioDecoder.dequeueOutputBuffer(audioBufferInfo, TIMEOUT_US);switch (outputBufferIndex) {case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:Log.d(TAG, "INFO_OUTPUT_FORMAT_CHANGED");break;case MediaCodec.INFO_TRY_AGAIN_LATER:Log.d(TAG, "INFO_TRY_AGAIN_LATER");break;case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:outputBuffers = mAudioDecoder.getOutputBuffers();Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED");break;default:ByteBuffer outputBuffer = mAudioDecoder.getOutputBuffer(outputBufferIndex); //outputBuffers[outputBufferIndex]; //SDK<21使用// 延时解码,跟视频时间同步while ((audioBufferInfo.presentationTimeUs / 1000) > (System.currentTimeMillis() - startMs)) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();break;}}// 如果解码成功,则将解码后的音频PCM数据用AudioTrack播放出来if (audioBufferInfo.size > 0) {if (mAudioOutTempBuf.length < audioBufferInfo.size) {mAudioOutTempBuf = new byte[audioBufferInfo.size];}outputBuffer.position(0);outputBuffer.get(mAudioOutTempBuf, 0, audioBufferInfo.size);outputBuffer.clear();if (mAudioTrack != null)mAudioTrack.write(mAudioOutTempBuf, 0, audioBufferInfo.size);}// 释放资源mAudioDecoder.releaseOutputBuffer(outputBufferIndex, false);break;}}mAudioDecoder.stop();mAudioDecoder.release();mAudioExtractor.release();mAudioTrack.stop();mAudioTrack.release();}public void close() {//do nothing frist}
}

src\main\java\com\android\demo\mediacodec\decode 

package com.android.mediacodec;public interface ICodecInterface {void videoSizeCallBack(int width, int height);
}

四.结束 

使用MediaCodec制作的一个简易视频播放器就完成了,核心的音、视频解码流程已在其中了,在此基础上可以丰富其他UI相关功能:进度条,播放/暂停,方向切换,视频播放界面放大缩小等,这些实现并不复杂,在此就不再探讨了。

http://www.hkea.cn/news/282987/

相关文章:

  • 学风建设网站版块设计个人网站
  • 网站底部连接怎么做福州seo推广
  • 生猪价格今日猪价行情关键词优化是什么工作
  • 网站建设公司下载搜索引擎查询
  • 韩国吃秀在哪个网站做直播企业宣传
  • 江西网站建设成都百度
  • 糯米团网站怎么做微信软文范例100字
  • 如何在社交网站上做视频推广seo营销的概念
  • 大连做网站仟亿科技最新域名查询
  • 网站开发实施计划与安排宁波网络推广方式
  • 企业网站建设公司注意哪些问题软件开发外包公司
  • abc网站建设怎么样yandex引擎搜索入口
  • wordpress屏蔽f12广州seo网络优化公司
  • 南宁网站建设推广服务云服务器免费
  • 大数据营销是什么seo站长
  • 建设政府网站的公司乐山网站seo
  • 仿站容易还是建站容易专业做灰色关键词排名
  • 做网站背景音乐管理课程培训
  • 网站建设可以自学吗品牌软文范文
  • 网站风格对比哪里有学计算机培训班
  • 做mla的网站网站优化哪家好
  • 网站注册的账号怎么注销线上营销活动有哪些
  • 国内做进口的电商网站网站推广软件哪个好
  • 谁有做那事的网站百度投诉中心入口
  • 免费单页网站在线制作沈阳seo排名优化教程
  • 廊坊网站建大型网站建站公司
  • 远程桌面做网站sem和seo区别与联系
  • 做贷款网站优化大师有用吗
  • 有没有便宜的网站制作制作网页教程
  • 医院网站制作优化关键词的方法有哪些