今天 学习 android多线程 atomininteger内存模型 以及自己项目的 视频播放功能
目前 对于android一些知识点 大家可以 去看今日头条的 android进阶小刘 这个博主 讲得很好
atomininteger内存模型 是啥
https://blog.csdn.net/fanrenxiang/article/details/80623884 没看懂
https://www.cnblogs.com/nightOfStreet/articles/11887169.html
好這裏说下我的視頻播放項目
我主要使用 videoView 去进行视频播放
xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns: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" android:background="@android:color/black" android:id="@+id/root_ll"><!-- 视频播放--> <VideoView android:id="@+id/videoPlayView" android:layout_width="match_parent" android:layout_height="450dp" android:layout_marginBottom="14dp" android:layout_marginLeft="12dp" android:layout_marginRight="12dp" android:layout_marginTop="15dp" /> <ImageButton android:id="@+id/ibBack" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="?android:listPreferredItemPaddingStart" android:background="@android:color/transparent" android:src="@drawable/ib_knight_return" /> </RelativeLayout>
xml文件很简单 主要是 VideoView的布局 去实现播放器的功能
activity代码 其实代码很简单 videoview的视频播放+缩略图背景 使用缩略图设置背景 然后在 加载完视频数据后 隐藏背景进行播放
package com.zsch.forestinventory.activity.left_activity; import android.graphics.Bitmap;import android.graphics.Color;import android.graphics.drawable.BitmapDrawable;import android.media.MediaMetadataRetriever;import android.media.MediaPlayer;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.os.Message;import android.view.MotionEvent;import android.view.View;import android.widget.ImageButton;import android.widget.ImageView;import android.widget.MediaController;import android.widget.Toast;import android.widget.VideoView;import android.support.annotation.Nullable;import com.zsch.androidlib.activity.BaseActivity;import com.zsch.forestinventory.BuildConfig;import com.zsch.forestinventory.R;import com.zsch.forestinventory.ui.overlay.controller.MeasureController; import java.io.IOException;import java.util.HashMap;import android.os.Handler;import android.util.Log;/** * 播放视频 */public class ShowVideoViewActivity extends BaseActivity implements View.OnClickListener { private ImageButton ibBack; private Uri uri; /其他页面传过来的 uri对象 private MediaController mc; //视频播放控制器 private int bufferPercentage = 0; private VideoView videoView; private ImageView first_frame; @Override protected void initVariables() { uri = getIntent().getData(); if (uri == null) finish(); } @Override protected void initView(Bundle savedInstanceState) { setContentView(R.layout.activity_show_video_view); if (savedInstanceState == null) { // Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的。实际上,savedInstanceState也就是保存Activity的状态的 //onsaveInstanceState方法是用来保存Activity的状态的。当一个Activity在生命周期结束前,会调用该方法保存状态 // 用来保存状态信息的Bundle会同时传给两个method,即onRestoreInstanceState() and onCreate(). uri = getIntent().getData(); } else { uri = savedInstanceState.getParcelable("uri"); } if (uri == null) { Toast.makeText(this, "无视频展示", Toast.LENGTH_SHORT).show(); finish(); return; } videoView = (VideoView) findViewById(R.id.videoPlayView); ibBack=(ImageButton) findViewById(R.id.ibBack); ibBack.setOnClickListener(this); mc = new MediaController(this); videoView.setMediaController(mc); //设置视频控制器,组件可以控制视频的播放,暂停,快进,组件,不需要你实现 videoView.setVideoURI(uri);//设置视频的播放地址 加载uri所对应的视频 String videoUrl=uri.getPath(); Bitmap bitmapfirst_frame=getBitmapFormUrl(videoUrl); //生成缩略图 videoView.setBackgroundDrawable(new BitmapDrawable(getResources(), bitmapfirst_frame)); //解決 黑屏方法 这里最重要 因为在视频家在之前 就是 prepared前 会显示为黑屏 用以下方法解决 //先在videoView設置背景 利用 本地視頻 制作缩略图 //等到视频真正开始渲染后再去掉VideoView 的背景。最终的解决办法是在onPrepared回调中,加添加一个setOnInfoListener的监听,在这个监听中将VideoView的背景清除 videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { //setOnPreparedListener 用于处理准备结束后的操作
@Override public void onPrepared(MediaPlayer mp) {// 装载完毕回调 时的方法 OnPreparedListener里的ononPrepared方法
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) // first_frame.setVisibility(View.GONE); //组件看不到,不占用布局空间 // videoView.setVisibility(View.VISIBLE); //组件可见 并占用空间 videoView.setBackgroundColor(Color.TRANSPARENT); //将VideoView的背景清除 将背景颜色 设置为空 return true; } }); } }); } // 生成視頻 首帧 缩略图 public static Bitmap getBitmapFormUrl(String url) { Bitmap bitmap = null; MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(url); //因为是本地视频 不考虑 sdk 版本 问题 网络 流媒体 考虑 全部// if (Build.VERSION.SDK_INT >= 14) {// retriever.setDataSource(url, new HashMap<String, String>());// } else {// retriever.setDataSource(url);// } /*getFrameAtTime()--->在setDataSource()之后调用此方法。 如果可能,该方法在任何时间位置找到代表性的帧, 并将其作为位图返回。这对于生成输入数据源的缩略图很有用。**/ bitmap = retriever.getFrameAtTime(); } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { try { retriever.release(); } catch (IllegalArgumentException e) { e.printStackTrace(); } } return bitmap; } @Override protected void onResume() { super.onResume();// try {// Toast.makeText(ShowVideoActivity.this, "1", Toast.LENGTH_LONG).show();// mediaPlayer.setDataSource(uri.getPath()); //播放存储设备的资源文件// mediaPlayer.setOnBufferingUpdateListener(this); //监听事件,网络流媒体的缓冲监听。这个方法与上个接口中的方法int getBufferPercentage()进行结合使用// //mediaPlayer.prepare();// controller.setMediaPlayer(this);// controller.setEnabled(true); //设置按钮可点击 false 设置为不可点击// }catch (IOException e){// e.printStackTrace();// } } @Override protected void loadData() { } @Override public void onClick(View view) { switch (view.getId()) { case R.id.ibBack: onBackPressed(); break; } } @Override public void onBackPressed() { finish(); // finish();//在Activity中执行this.finish()方法之后,执行如下过程: onPause(),onStop(),onDestory(), } @Override public boolean onTouchEvent(MotionEvent event) { //实现这个方法来处理触摸屏幕引发的事件。 return super.onTouchEvent(event); } }
原文地址:https://www.cnblogs.com/dushutai/p/12658741.html
时间: 2024-11-09 02:05:27