Android 第二十五章 SurfaceView

一、继承

java.lang.Object
↳ android.view.View
↳ android.view.SurfaceView

二、公共方法

  1. applyTransactionToFrame(SurfaceControl.Transaction transaction) 添加将与显示 SurfaceView 的下一个同步应用的事务 框架。
  2. draw(Canvas canvas) 将此视图(及其所有子视图)手动呈现到给定的画布。
  3. gatherTransparentRegion(Region region) ViewRoot 使用它在以下情况下执行优化 视图层次结构包含一个或多个 SurfaceView。
  4. getHolder() 返回提供对此的访问和控制的 SurfaceHolder SurfaceView 的底层表面。
  5. getHostToken() 用于构造的令牌 SurfaceControlViewHost.
  6. getImportantForAccessibility() 获取用于确定SurfaceView是否对辅助功能很重要的模式。
  7. getSurfaceControl() 将可用于父级界面的 SurfaceControl 返回到此 SurfaceView。
  8. hasOverlappingRendering() 返回SurfaceView是否具有重叠的内容。
  9. setAlpha(float alpha) 将SurfaceView的不透明度设置为 0 到 1 之间的值,其中 0 表示SurfaceView 完全透明,1 表示SurfaceView完全不透明。
  10. setChildSurfacePackage(SurfaceControlViewHost.SurfacePackage p) 显示嵌入在 SurfaceControlViewHost.SurfacePackage 在此 SurfaceView 中。
  11. setClipBounds(Rect clipBounds) 在此视图上设置视图将剪裁到的矩形区域 当它被绘制时。
  12. setSecure(boolean isSecure) 控制是否应将SurfaceView的内容视为安全视图, 防止它出现在屏幕截图中或被查看 不安全的显示器。
  13. setSurfaceLifecycle(int lifecycleStrategy) 控制此 SurfaceView 拥有的 Surface 的生命周期。
  14. setVisibility(int visibility) 设置view 是否显示
  15. setZOrderMediaOverlay(boolean isMediaOverlay) 控制是否将SurfaceView 放置在另一个view之上 窗口中的规则表面视图(但仍在窗口本身后面)。
  16. setZOrderOnTop(boolean onTop) 设置将SurfaceView视图显示在窗口顶部

三、播放视频

/**
 *
 *
 * 权限
 *  允许应用可以联网
 *  <uses-permission android:name="android.permission.INTERNET" />
 *  写入权限
 *  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 *  读取权限
 *  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 *
 *  //视频缓存
 *  implementation 'com.danikula:videocache:2.7.1'
 *
 *  maven { url "https://maven.aliyun.com/repository/public/" }
 *  maven { url "https://jitpack.io" }
 *
 *
 * <application  android:name=".MyApplication"
 *
 */
public class MyApplication extends Application {

    private static MyApplication myApplication;
    private HttpProxyCacheServer mProxy;

    public static MyApplication getInstance() {
        return myApplication == null ? (myApplication = new MyApplication()) : myApplication;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    //视频缓存
    public HttpProxyCacheServer getProxy() {
        MyApplication mApplication = MyApplication.getInstance();
        return mApplication.mProxy == null ? (mApplication.mProxy = mApplication.newProxy()) : mApplication.mProxy;
    }

    /**
     * maxCacheSize 设置最大缓存大小(以字节为单位)。默认值为512 Mb
     * 1024B=1KB,1024KB=1MB,1024MB=1GB
     * maxCacheFilesCount 设置最大缓存文件数
     * cacheDirectory
     * 覆盖用于缓存文件的默认缓存文件夹。
     * 默认情况下,
     * 如果安装了卡并且应用程序具有适当的权限,
     * 则AndroidVideoCache使用“/Android/data/[app_package_name]/cache/video-cache/”,
     * 否则在默认应用程序的缓存目录中使用“视频缓存”子目录。
     */
    private HttpProxyCacheServer newProxy() {
        return new HttpProxyCacheServer.Builder(MyApplication.getInstance().getApplicationContext())
                .maxCacheSize(1024 * 1024 * 1024)
                .maxCacheFilesCount(3)
                .cacheDirectory(getSaveVideoFile())
                .build();
    }

    public File getSaveVideoFile() {
        File esd = Environment.getExternalStorageDirectory();

        File f1 = new File(esd.getPath() + "/TestDemo");
        if (!f1.exists()) {
            f1.mkdir();
        }

        File file = new File(esd.getPath() + "/TestDemo/video/");
        if (!file.exists()) {
            file.mkdir();
        }

        return file;
    }
}

public class MainActivity extends AppCompatActivity {

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;
    private MediaPlayer mMediaPlayer;
    private HttpProxyCacheServer mProxy;
    private ArrayList<String> videoURL;
    private int playIndex = 0;


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

    private void initView() {
        mSurfaceView = findViewById(R.id.surfaceView);
    }

    private void initData() {
        playIndex = 0;
        videoURL = new ArrayList<>();
        mProxy = MyApplication.getInstance().getProxy();
        initMediaPlayer();
        initSurfaceHolder();
        updateAD();

//        缓存视频
//        String videoPath = mProxy.getProxyUrl("https://xxx");
//        videoURL.add(videoPath);
//        loopPlayback();
    }

    private void initSurfaceHolder() {
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {

            //在创建时调用
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if (null != mMediaPlayer) {
                    mMediaPlayer.setDisplay(holder);
                }
            }

            //surface的格式或大小发生改变时调用
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                if (null != mMediaPlayer) {
                    mMediaPlayer.setDisplay(holder);
                }
            }

            //销毁时调用
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
    }

    private void initMediaPlayer() {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    }

    private void loopPlayback() {

        if (videoURL.size() > 0) {
            setMediaPlayer(videoURL.get(0));
        } else {
            updateAD();
        }

        mMediaPlayer.setOnCompletionListener(player -> {
            playIndex++;
            if (playIndex < videoURL.size()) {
                setMediaPlayer(videoURL.get(playIndex));
            } else {
                playIndex = 0;
                loopPlayback();
            }
        });
    }

    private void setMediaPlayer(String path) {
        try {
            mMediaPlayer.reset();
            //添加音频/视频数据源
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateAD() {
        File file = new File(Environment.getExternalStorageDirectory().getPath() + "/TestDemo/video/");
        if (file.exists()) {
            File[] files = file.listFiles();
            if (null != files) {
                if (null == videoURL) {
                    videoURL = new ArrayList<>();
                } else {
                    videoURL.clear();
                }
                for (int i = 0; i < files.length; i++) {
                    videoURL.add(files[i].getPath());
                }
                if (videoURL.size() > 0) {
                    loopPlayback();
                }
            }
        }
    }

}
<?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:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值