ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021-04-02

2021-04-02 09:30:44  阅读:135  来源: 互联网

标签:02 04 mediaPlayer void int 2021 tv new public


自定义视图视频加弹幕
视频布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp">
        <com.example.day11_surfaceview.view.YaoVideoView
            android:id="@+id/yao"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></com.example.day11_surfaceview.view.YaoVideoView>
        <LinearLayout
            android:layout_alignParentBottom="true"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:id="@+id/tv_start"
                android:text="   播放/暂停   "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"></TextView>

            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:id="@+id/tv_quick"
                android:text="   快进  "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"></TextView>
            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:id="@+id/tv_tui"
                android:text="   快退   "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"></TextView>
            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:id="@+id/tv_bei"
                android:text="   倍速   "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"></TextView>
            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:id="@+id/tv_full"
                android:text="   全屏   "
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"></TextView>
        </LinearLayout>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:text="00:00"
                android:id="@+id/tv_current"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"></TextView>
            <SeekBar
                android:id="@+id/bar"
                android:layout_width="0dp"
                android:layout_weight="7"
                android:layout_height="wrap_content"></SeekBar>
            <TextView
                android:textSize="17sp"
                android:textColor="#fff"
                android:text="00:00"
                android:id="@+id/tv_duration"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"></TextView>
        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

视频自定义视图

public class YaoVideoView extends SurfaceView implements SurfaceHolder.Callback {
    private MediaPlayer mediaPlayer = new MediaPlayer();
    //设置视频资源
    public void setData(String path){
        if(mediaPlayer != null){
            mediaPlayer.reset();//重置
            try {
                mediaPlayer.setDataSource(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mediaPlayer.start();
                }
            });

        }
    }

    public void init(){
        getHolder().addCallback(this);//获得surfaceview的生命周期
    }
    public YaoVideoView(Context context) {//java代码执行该构造
        super(context);
        init();
    }

    public YaoVideoView(Context context, AttributeSet attrs) {//xml布局执行该构造,一般是他
        super(context, attrs);
        init();
    }

    public YaoVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public YaoVideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        Log.d("ytx", "被创建了: ");
        if (mediaPlayer != null){
            mediaPlayer.setDisplay(holder);//展示视频画面
        }

    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
        Log.d("ytx", "改变了: ");
    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
        Log.d("ytx", "销毁了: ");
        if(mediaPlayer != null){
            mediaPlayer.release();//释放资源
            mediaPlayer = null;
        }

    }

    /**
     * 播放和暂停
     */
    public void play(){
        if (mediaPlayer != null){
            if(mediaPlayer.isPlaying()){
                mediaPlayer.pause();
            }else{
                mediaPlayer.start();
            }
        }
    }

    /**
     * 快进3秒
     */
    public void quick(){
        if(mediaPlayer != null){
            int currentPosition = mediaPlayer.getCurrentPosition();//获得当前进度
            currentPosition+=3000;
            mediaPlayer.seekTo(currentPosition);//播放到指定进度
        }
    }

    /**
     * 快退3秒
     */
    public void tui(){
        if(mediaPlayer != null){
            int currentPosition = mediaPlayer.getCurrentPosition();//获得当前进度
            currentPosition-=3000;
            mediaPlayer.seekTo(currentPosition);//播放到指定进度
        }
    }

    /**
     * 倍速播放
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void bei(){
        if(mediaPlayer != null){
            PlaybackParams playbackParams = mediaPlayer.getPlaybackParams();//获得播放参数
            playbackParams.setSpeed(2f);//修改速度
            mediaPlayer.setPlaybackParams(playbackParams);//设置回去

        }
    }

    /**
     * 获得当前进度
     * @return
     */
    public int getCurrrent(){
        if(mediaPlayer != null){
            return mediaPlayer.getCurrentPosition();
        }
        return 0;
    }

    /**
     * 获得当前时间 00:00
     */
    public String getCurrrentStr(){
        if(mediaPlayer != null){
            int currentPosition = mediaPlayer.getCurrentPosition();//毫秒
            SimpleDateFormat format = new SimpleDateFormat("mm:ss");//将毫秒---》00:00
            String format1 = format.format(currentPosition);
            return format1;

        }
        return "00:00";
    }

    /**
     * 获得总长度
     * @return
     */
    public int getDuration(){
        if(mediaPlayer != null){
            return mediaPlayer.getDuration();
        }
        return 0;
    }
    /**
     * 获得总时间 00:00
     */
    public String getDurationStr(){
        if(mediaPlayer != null){
            int currentPosition = mediaPlayer.getDuration();//毫秒
            SimpleDateFormat format = new SimpleDateFormat("mm:ss");//将毫秒---》00:00
            String format1 = format.format(currentPosition);
            return format1;

        }
        return "00:00";
    }

    /***
     * 拖动进度条
     * @param progress
     */
    public void seekTo(int progress){
        if(mediaPlayer != null){
            mediaPlayer.seekTo(progress);
        }
    }
}

主页面

public class MainActivity extends AppCompatActivity {
    private YaoVideoView yaoVideoView;
    private TextView tv_start;
    private TextView tv_quick;
    private TextView tv_tui;
    private TextView tv_bei;
    private TextView tv_full;
    private TextView tv_current;
    private SeekBar bar;
    private TextView tv_duration;
    private Timer timer;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            requestPermissions(new String[]{
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            },101);
        }
        initView();
        initTimer();
    }

    private void initTimer() {
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                final int duration = yaoVideoView.getDuration();
                final int currrent = yaoVideoView.getCurrrent();
                final String durationStr = yaoVideoView.getDurationStr();
                final String currrentStr = yaoVideoView.getCurrrentStr();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        bar.setMax(duration);
                        bar.setProgress(currrent);
                        tv_duration.setText(durationStr+"");
                        tv_current.setText(currrentStr+"");

                    }
                });
            }
        },0,100);
    }

    private void initView() {
        tv_start = (TextView) findViewById(R.id.tv_start);
        tv_quick = (TextView) findViewById(R.id.tv_quick);
        tv_tui = (TextView) findViewById(R.id.tv_tui);
        tv_bei = (TextView) findViewById(R.id.tv_bei);
        tv_full = (TextView) findViewById(R.id.tv_full);
        tv_current = (TextView) findViewById(R.id.tv_current);
        bar = (SeekBar) findViewById(R.id.bar);
        tv_duration = (TextView) findViewById(R.id.tv_duration);
        yaoVideoView = findViewById(R.id.yao);
        yaoVideoView.setData("/sdcard/Movies/1807A.mp4");//播放视频
        tv_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                yaoVideoView.play();
            }
        });
        tv_quick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                yaoVideoView.quick();
            }
        });
        tv_tui.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                yaoVideoView.tui();
            }
        });

        tv_bei.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onClick(View v) {
                yaoVideoView.bei();
            }
        });
        tv_full.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                change();
            }
        });
        bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if(fromUser){
                   yaoVideoView.seekTo(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
    }
    //横竖屏切换---????视频重头播放---》activity会重新执行---》清单文件配置
    private void change() {
        int width = getWindow().getDecorView().getWidth();
        int height = getWindow().getDecorView().getHeight();
        if(width >= height){//横屏---》竖屏
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//PORTRAIT 肖像 竖着
        }else{//竖屏--->横屏
           setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//LANDSCAPE 山水画 横着
        }
    }
}

/
普通弹幕视图

/***
  绘制文字:
  1.画笔:Paint
  2.画布:Canvas


 */
public class DanMuView extends SurfaceView implements SurfaceHolder.Callback {
    public void init(){
        getHolder().addCallback(this);
        setZOrderOnTop(true);//置顶
        getHolder().setFormat(PixelFormat.TRANSPARENT);//透明
    }
    public DanMuView(Context context) {
        super(context);
        init();
    }

    public DanMuView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DanMuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public DanMuView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }
    private float x = 200;
    //创建:绘制文字
    @Override
    public void surfaceCreated(@NonNull final SurfaceHolder holder) {
        //TODO 1:画笔对象
        final Paint paint = new Paint();
        paint.setColor(Color.GREEN);//颜色
        paint.setStrokeWidth(10);//粗细
        paint.setTextSize(50);//文字大小
        //TODO 2:画布
//        Canvas canvas = holder.lockCanvas();//锁定画布
//        canvas.drawText("真帅!!!!!",200,400,paint);
//        holder.unlockCanvasAndPost(canvas);//解除锁定画布,必须写不然就报错
        //动态文字移动
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    Canvas canvas = holder.lockCanvas();//锁定画布
                    canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);//将之前写的内容清空                  
                    canvas.drawText("真帅!!!!!",x++,400,paint);
                    holder.unlockCanvasAndPost(canvas);//解除锁定画布,必须写不然就报错
                }
            }
        }).start();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }
    //销毁
    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }
}

高级弹幕

public class GaoJiDanMuView extends SurfaceView implements SurfaceHolder.Callback {
    private List<GaoJiDanMuEntity> list = new ArrayList<>();
    //添加弹幕
    public void addDanMu(GaoJiDanMuEntity gaoJiDanMuEntity){
        list.add(gaoJiDanMuEntity);
    }
    public void init(){

        getHolder().addCallback(this);
        list.add(new GaoJiDanMuEntity("我是穷鬼",20,200,false));
        list.add(new GaoJiDanMuEntity("我是富二代",40,300,true));
        list.add(new GaoJiDanMuEntity("没钱真帅",30,400,false));
        list.add(new GaoJiDanMuEntity("有钱真好",0,180,true));
    }
    public GaoJiDanMuView(Context context) {
        super(context);
        init();
    }

    public GaoJiDanMuView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public GaoJiDanMuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public GaoJiDanMuView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }
    //绘制多条弹幕
    @Override
    public void surfaceCreated(@NonNull final SurfaceHolder holder) {
        //会员画笔
        final Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setTextSize(70);

        //非会员画笔
        final Paint paint2 = new Paint();
        paint2.setColor(Color.GREEN);
        paint2.setTextSize(50);


        //文字动态
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    Canvas canvas = holder.lockCanvas();
                    canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
                    for (int i = 0; i < list.size(); i++) {
                        String text = list.get(i).getText();//文字
                        float x = list.get(i).getX();//x坐标
                        float y = list.get(i).getY();//y坐标
                        boolean vip = list.get(i).isVip();//是否为vip
                        if(vip){
                            canvas.drawText(text,x,y,paint);
                        }else{
                            canvas.drawText(text,x,y,paint2);
                        }
                        x++;
                        list.get(i).setX(x);//设置新的x坐标
                    }

                    holder.unlockCanvasAndPost(canvas);
                }

            }
        }).start();
    }

    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }
}

清单文件

 <!-- configChanges 当屏幕方向 键盘 大小 发生改变的时候生命周期不会重新执行 -->
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboard|screenSize"></activity>

视频弹幕交互

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".VideoDanMuActivity">
    <com.example.day11_surfaceview.view.YaoVideoView
        android:id="@+id/yao"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.example.day11_surfaceview.view.YaoVideoView>
    <com.example.day11_surfaceview.view.GaoJiDanMuView
        android:id="@+id/danmu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.example.day11_surfaceview.view.GaoJiDanMuView>
    <LinearLayout
        android:layout_alignParentBottom="true"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"></EditText>
        <Button
            android:id="@+id/bt_send"
            android:text="发送"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"></Button>
    </LinearLayout>
</RelativeLayout>

主页面

public class VideoDanMuActivity extends AppCompatActivity {

    private YaoVideoView yao;
    private GaoJiDanMuView danmu;
    private EditText editText;
    private Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_dan_mu);
        initView();
    }

    private void initView() {
        yao = (YaoVideoView) findViewById(R.id.yao);
        danmu = (GaoJiDanMuView) findViewById(R.id.danmu);
        editText = findViewById(R.id.et);
        button = findViewById(R.id.bt_send);
        yao.setData("/sdcard/Movies/1807A.mp4");//播放视频
        danmu.setZOrderOnTop(true);//弹幕置顶
        danmu.getHolder().setFormat(PixelFormat.TRANSPARENT);//弹幕透明的

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String trim = editText.getText().toString().trim();
                danmu.addDanMu(new GaoJiDanMuEntity(trim,0,400,true));
            }
        });

    }
}

标签:02,04,mediaPlayer,void,int,2021,tv,new,public
来源: https://blog.csdn.net/hcn456/article/details/115390574

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有