马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
1.视频解码类
- import android.media.MediaCodec;
- import android.media.MediaFormat;
- import java.nio.ByteBuffer;
- public class VideoDecoder {
- private MediaCodec mediaCodec;
- public void initDecoder(String mimeType, int width, int height) throws IOException {
- // 创建 MediaCodec 实例
- mediaCodec = MediaCodec.createDecoderByType(mimeType);
- // 配置 MediaCodec
- MediaFormat mediaFormat = MediaFormat.createVideoFormat(mimeType, width, height);
- mediaCodec.configure(mediaFormat, null, null, 0);
- // 启动解码器
- mediaCodec.start();
- }
- public void decode(byte[] inputData) {
- // 获取输入缓冲区索引
- int inputBufferIndex = mediaCodec.dequeueInputBuffer(10000);
- if (inputBufferIndex >= 0) {
- ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
- inputBuffer.clear();
- inputBuffer.put(inputData);
- // 将数据提交到解码器
- mediaCodec.queueInputBuffer(inputBufferIndex, 0, inputData.length, 0, 0);
- }
- // 获取输出缓冲区索引
- MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
- int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 10000);
- while (outputBufferIndex >= 0) {
- ByteBuffer outputBuffer = mediaCodec.getOutputBuffer(outputBufferIndex);
- // 处理解码后的数据
- // TODO: 将 outputBuffer 中的数据进行处理或渲染
- // 释放输出缓冲区
- mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
- outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
- }
- }
- public void release() {
- // 停止并释放解码器
- mediaCodec.stop();
- mediaCodec.release();
- mediaCodec = null;
- }
- }
复制代码 2.视频渲染
- public class VideoPlayerActivity extends Activity {
- private SurfaceView surfaceView;
- private SurfaceHolder surfaceHolder;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_video_player);
- surfaceView = findViewById(R.id.surface_view);
- surfaceHolder = surfaceView.getHolder();
- surfaceHolder.addCallback(new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- // 初始化解码器并开始解码
- initMediaCodec(holder.getSurface());
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
- });
- }
- }
复制代码- private MediaCodec mediaCodec;
- private void initMediaCodec(Surface surface) {
- try {
- mediaCodec = MediaCodec.createDecoderByType("video/avc"); // H.264
- MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 1920, 1080);
- mediaCodec.configure(mediaFormat, surface, null, 0);
- mediaCodec.start();
- // 启动解码线程
- new Thread(new DecodeRunnable()).start();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
复制代码- private class DecodeRunnable implements Runnable {
- @Override
- public void run() {
- while (true) {
- int inputBufferIndex = mediaCodec.dequeueInputBuffer(10000);
- if (inputBufferIndex >= 0) {
- ByteBuffer inputBuffer = mediaCodec.getInputBuffer(inputBufferIndex);
- // 读取视频数据到inputBuffer中
- int sampleSize = readSampleData(inputBuffer);
- if (sampleSize < 0) {
- // 视频数据读取结束
- mediaCodec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
- break;
- } else {
- mediaCodec.queueInputBuffer(inputBufferIndex, 0, sampleSize, presentationTimeUs, 0);
- }
- }
- MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
- int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 10000);
- if (outputBufferIndex >= 0) {
- mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
- }
- }
- mediaCodec.stop();
- mediaCodec.release();
- }
- private int readSampleData(ByteBuffer inputBuffer) {
- // 实现视频数据读取逻辑,例如从文件或网络流中读取
- return sampleSize;
- }
- }
复制代码 3.读取本地视频文件
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
复制代码- import android.media.MediaExtractor;
- import android.media.MediaFormat;
- import java.io.IOException;
- public class VideoReader {
- public void readVideoData(String filePath) {
- MediaExtractor extractor = new MediaExtractor();
- try {
- // 设置数据源(文件路径)
- extractor.setDataSource(filePath);
- // 获取轨道数量
- int trackCount = extractor.getTrackCount();
- for (int i = 0; i < trackCount; i++) {
- MediaFormat format = extractor.getTrackFormat(i);
- String mime = format.getString(MediaFormat.KEY_MIME);
- // 选择视频轨道
- if (mime.startsWith("video/")) {
- extractor.selectTrack(i);
- break;
- }
- }
- // 读取视频数据
- while (true) {
- int sampleSize = extractor.readSampleData(byteBuffer, 0);
- if (sampleSize < 0) {
- // 读取完成
- break;
- }
- // 处理视频数据
- byte[] videoData = new byte[sampleSize];
- byteBuffer.get(videoData, 0, sampleSize);
- // 前进到下一个样本
- extractor.advance();
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- extractor.release();
- }
- }
- }
复制代码 4.从网络流读取视频数据:
实现MediaDataSource
- import android.media.MediaDataSource;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- public class NetworkMediaDataSource extends MediaDataSource {
- private InputStream inputStream;
- public NetworkMediaDataSource(String urlStr) throws IOException {
- URL url = new URL(urlStr);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- inputStream = connection.getInputStream();
- }
- @Override
- public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
- inputStream.skip(position);
- return inputStream.read(buffer, offset, size);
- }
- @Override
- public long getSize() throws IOException {
- return -1; // 未知大小
- }
- @Override
- public void close() throws IOException {
- inputStream.close();
- }
- }
复制代码 使用MediaExtractor读取网络视频数据:
- import android.media.MediaExtractor;
- import android.media.MediaFormat;
- import java.io.IOException;
- public class NetworkVideoReader {
- public void readNetworkVideoData(String urlStr) {
- MediaExtractor extractor = new MediaExtractor();
- try {
- // 设置数据源(网络流)
- NetworkMediaDataSource mediaDataSource = new NetworkMediaDataSource(urlStr);
- extractor.setDataSource(mediaDataSource);
- // 获取轨道数量
- int trackCount = extractor.getTrackCount();
- for (int i = 0; i < trackCount; i++) {
- MediaFormat format = extractor.getTrackFormat(i);
- String mime = format.getString(MediaFormat.KEY_MIME);
- // 选择视频轨道
- if (mime.startsWith("video/")) {
- extractor.selectTrack(i);
- break;
- }
- }
- // 读取视频数据
- while (true) {
- int sampleSize = extractor.readSampleData(byteBuffer, 0);
- if (sampleSize < 0) {
- // 读取完成
- break;
- }
- // 处理视频数据
- byte[] videoData = new byte[sampleSize];
- byteBuffer.get(videoData, 0, sampleSize);
- // 前进到下一个样本
- extractor.advance();
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- extractor.release();
- }
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |