• 安卓 日常问题 工作日志18


    今天 学习 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);
    }



    }

            

  • 相关阅读:
    Android特效专辑(一)——水波纹过渡特效(首页)
    简单整数算术运算
    Python 获取新浪微博的热门话题 (API)
    比真机还快的Android模拟器——Genymotion
    兔子--CheckBox与Radiobutton的差别
    hdu oj 3127 WHUgirls(2009 Asia Wuhan Regional Contest Online)
    python中列表,元组,字符串如何互相转换
    典型LoadRunner脚本
    LoadRunner显示中文乱码的问题
    如何解决paramiko执行与否的问题
  • 原文地址:https://www.cnblogs.com/dushutai/p/12658741.html
Copyright © 2020-2023  润新知