android surfaceview学习(一)

本文详细介绍了Android中使用SurfaceView进行视频播放时遇到的各种问题和解决方案,包括SurfaceView的背景颜色、层级管理、显示与隐藏、延迟问题以及Surface的生命周期管理。同时提供了示例代码,展示了如何在两个SurfaceView之间切换播放视频。
部署运行你感兴趣的模型镜像

推荐阅读:
https://blog.youkuaiyun.com/luoshengyang/article/details/8661317
https://www.cnblogs.com/xuling/archive/2011/06/06/android.html
https://blog.youkuaiyun.com/zcmain/article/details/14454953

1、surfaceview默认是黑色的背景,并且给sfv设置背景颜色会覆盖在播放的画面上
在这里插入图片描述
2、上下层surfaceview,当下层sfv开始播放画面,上层sfv自动会变为透明
在这里插入图片描述
3、当上层surfaceview gone之后,父布局设置的背景色才会生效
在这里插入图片描述
4、一旦sfv gone,就会回调surfaceDestroyed,surface先销毁,之后sfv被隐藏,重新显示时候,需要再次在surfaceCreated回调中绑定
mediaPlayer2.setDisplay(holder);
否则sfv会没有画面,好像被挖空,显示下层画面
在这里插入图片描述
5、当下层、上层surfaceview都在播放视频,上层sfv 的父布局 gone了,会发现上层surfaceview依旧显示,无法隐藏掉。
要想讲sfv隐藏,需要同时
父布局 gone
sfv gone
在这里插入图片描述
6、延迟问题:
surfaceview变得可见时,surface才会被创建,导致:
会出现surfaceview先透明,后出现画面;

surfaceview隐藏之前,surface先被销毁,导致:
透明之后,才会被隐藏。

7、下层surfaceview已经在播放画面,上层sfv会变成透明的(sfv背景颜色生效,所有的父布局颜色均无效),一旦上层sfv mediaplay播放准备耗时,透明时间就会变长。比如;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mediaPlayer2.start();
}
}, 1000);
在这里插入图片描述
还有很多情况,大家可以自行测试,手机上最后使用
String uri = “android.resource://” + getPackageName() + “/” + R.raw.b;
mediaPlayer1.setDataSource(this, Uri.parse(uri));//设置要播放的内容在根目录下的位置
sd卡读取容易出现异常。

package com.example.myapplication.videoplayer;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.example.myapplication.R;

public class VideoPlayActivity2 extends AppCompatActivity implements View.OnClickListener {
    Button start, pause, stop;
    MediaPlayer mediaPlayer2;
    SurfaceHolder surfaceHolder2;

    Button start1, hidesfv, showsfv, change;

    SurfaceView sfv1, sfv2;

    TextView info;
    FrameLayout sfvfmlayout;
    FrameLayout sfv2fmlayout;

    SurfaceHolder surfaceHolder1;
    MediaPlayer mediaPlayer1 = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_play2);
        int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
        }

        start1 = findViewById(R.id.start1);
        start1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playVideo1();
            }
        });

        info = findViewById(R.id.info);
        start = findViewById(R.id.start);
        start.setOnClickListener(this);

        change = findViewById(R.id.change);
        change.setOnClickListener(this);


        pause = findViewById(R.id.pause);
        pause.setOnClickListener(this);

        stop = findViewById(R.id.stop);
        stop.setOnClickListener(this);

        sfvfmlayout = findViewById(R.id.flsfv1);
        sfv2fmlayout = findViewById(R.id.flsfv2);

        sfv1 = findViewById(R.id.sfv1);
        sfv2 = findViewById(R.id.sfv2);

        showsfv = findViewById(R.id.show);
        hidesfv = findViewById(R.id.hide);

        hidesfv.setOnClickListener(this);
        showsfv.setOnClickListener(this);

        isstop = true;//初始化,处于停止播放中

        //大屏幕
        surfaceHolder1 = sfv1.getHolder();
        surfaceHolder1.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "surfaceHolder1 surfaceCreated");
//                new Handler().postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
                playVideo1();
//                    }
//                }, 5000);
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.d(TAG, "surfaceHolder1 surfaceChanged");

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "surfaceHolder1 surfaceDestroyed");

            }
        });

        //小屏幕
        surfaceHolder2 = sfv2.getHolder();
        surfaceHolder2.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d(TAG, "surfaceHolder2 surfaceCreated holder=" + holder);
                playVideo2();
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.d(TAG, "surfaceHolder2 surfaceChanged holder=" + holder);

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "surfaceHolder2 surfaceDestroyed holder=" + holder);

            }
        });

    }


    void playVideo2() {//小屏幕
        mediaPlayer2 = new MediaPlayer();
        isstop = false;
        mediaPlayer2.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer2.reset();//重置MediaPlayer
        mediaPlayer2.setDisplay(surfaceHolder2);//把视频画面输出到SurfaceView中
        try {
            //获取raw.mp4的uri地址
            String uri = "android.resource://" + getPackageName() + "/" + R.raw.a;
            mediaPlayer2.setDataSource(this, Uri.parse(uri));//设置要播放的内容在根目录下的位置
            mediaPlayer2.prepare();//预加载
            info.setText("播放中");
        } catch (Exception e) {
            e.printStackTrace();
        }

        mediaPlayer2.start();

    }

    void playVideo1() {//大屏幕
        mediaPlayer1 = new MediaPlayer();
        mediaPlayer1.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer1.reset();//重置MediaPlayer
        mediaPlayer1.setDisplay(surfaceHolder1);//把视频画面输出到SurfaceView中

        try {
            //获取raw.mp4的uri地址
            String uri = "android.resource://" + getPackageName() + "/" + R.raw.b;
            mediaPlayer1.setDataSource(this, Uri.parse(uri));//设置要播放的内容在根目录下的位置
            mediaPlayer1.prepare();//预加载
        } catch (Exception e) {
            e.printStackTrace();
        }
//        new Handler().postDelayed(new Runnable() {
//            @Override
//            public void run() {
        mediaPlayer1.start();
//            }
//        }, 1000);

    }

    boolean ispause = false;
    boolean isstop = true;

    String TAG = "lihui";

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.hide:
                sfv2fmlayout.setVisibility(View.GONE);
                sfv2.setVisibility(View.GONE);//GONE、INVISIBLE 父布局背景才有效果
//                if (mediaPlayer2 != null) {
//                    try {
//                        mediaPlayer2.pause();
//                        mediaPlayer2.stop();
//                        mediaPlayer2.release();
//                        isstop = true;
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
                break;
            case R.id.show:
                sfv2fmlayout.setVisibility(View.VISIBLE);
//                sfv2.postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
                sfv2.setVisibility(View.VISIBLE);
//                    }
//                }, 3000);

                break;


            case R.id.start:
                Log.d(TAG, "1 isstop=" + isstop + ",ispause=" + ispause);
                if (isstop) {
                    playVideo2();
                    isstop = false;
                } else if (ispause) {
                    mediaPlayer2.start();
                    ispause = false;
                }
                info.setText("播放中");
                break;
            case R.id.pause:
                Log.d(TAG, "2 isstop=" + isstop + ",ispause=" + ispause);
                if (mediaPlayer2 == null || isstop) return;
                if (mediaPlayer2.isPlaying()) {
                    mediaPlayer2.pause();
                    ispause = true;
                    info.setText("已暂停");
                }
                break;
            case R.id.stop:
                Log.d(TAG, "3 isstop=" + isstop + ",ispause=" + ispause);
                if (mediaPlayer2 == null || isstop) return;
                mediaPlayer2.stop();
                mediaPlayer2.release();
                info.setText("已停止");
                isstop = true;
                break;

            case R.id.change:
                ViewGroup.LayoutParams layoutParams1 = sfvfmlayout.getLayoutParams();
                ViewGroup.LayoutParams layoutParams2 = sfv2fmlayout.getLayoutParams();

                sfvfmlayout.setLayoutParams(layoutParams2);
                sfv2fmlayout.setLayoutParams(layoutParams1);
                sfv2.setZOrderMediaOverlay(true);
                sfv1.setZOrderMediaOverlay(true);

                if (sfvfmlayout.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT) {
                    sfv2fmlayout.bringToFront();//sfv2小屏幕

                    stop2();
                    playVideo2();
                    //sfv2.setVisibility(View.VISIBLE);
                    Log.d(TAG, "playVideo2");


                } else {
                    sfvfmlayout.bringToFront();//sfv1小屏幕
                    stop1();
                    playVideo1();
                    //  sfv1.setVisibility(View.VISIBLE);
                    Log.d(TAG, "playVideo1");

                }


                break;
        }
    }

    void stop1() {
        try {
            if (mediaPlayer1 != null) {
                mediaPlayer1.stop();
                mediaPlayer1.release();
                Log.d(TAG, "stop1");
            }
        } catch (Exception e) {
        }

    }

    void stop2() {
        try {
            if (mediaPlayer2 != null) {
                mediaPlayer2.stop();
                mediaPlayer2.release();
                Log.d(TAG, "stop2");
            }
        } catch (Exception e) {
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stop1();
        stop2();
    }
}

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".videoplayer.VideoPlayActivity">

        <FrameLayout
            android:id="@+id/parent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <FrameLayout
                android:id="@+id/flsfv1"
                android:layout_width="match_parent"
                android:layout_height="250dp">

                <SurfaceView
                    android:id="@+id/sfv1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:visibility="visible" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="30dp"
                    android:layout_gravity="bottom"
                    android:text="主画面"
                    android:textColor="#ff5500"
                    android:textSize="20dp" />
            </FrameLayout>


            <FrameLayout
                android:id="@+id/flsfv2"
                android:layout_width="100dp"
                android:layout_height="150dp"
                android:layout_gravity="bottom|right"
                android:visibility="visible">

                <SurfaceView
                    android:id="@+id/sfv2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

                <TextView
                    android:id="@+id/info"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:text="停止"
                    android:textColor="#ff5500"
                    android:textSize="20dp" />
            </FrameLayout>
        </FrameLayout>

        <Button
            android:id="@+id/start1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="surfaceview1播放" />

        <Button
            android:id="@+id/start"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="surfaceview2播放" />

        <Button
            android:id="@+id/pause"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:text="surfaceview2暂停" />

        <Button
            android:id="@+id/stop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:text="surfaceview2停止" />

        <Button
            android:id="@+id/hide"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:text="surfaceview2隐藏" />

        <Button
            android:id="@+id/show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="surfaceview2显示" />


        <Button
            android:id="@+id/change"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="交换surfaceview1、2位置" />

    </LinearLayout>
</ScrollView>

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值