Android开发视频预览效果

Android开发视频预览效果

视频播放不是一个简单的事情,得有暂停,继续播放等功能,屏幕的适配也是头疼的事情

一、思路:

引用的是腾讯播放器TXVodPlayer

二、效果图:

在这里插入图片描述图片不是很直观,也可以看下视频

Android开发教程实战案例源码分享-视频预览效果

三、关键代码:
public class ActiveVideoPreviewDialog extends AbsDialogFragment implements View.OnClickListener, ITXLivePlayListener {public static final String VIDEO_PATH = "videoPath";private TXCloudVideoView mTXCloudVideoView;private TXVodPlayer mPlayer;private String mVideoPath;private ObjectAnimator mPlayBtnAnimator;//暂停按钮的动画private View mPlayBtn;private boolean mPlayStarted;//播放是否开始了private boolean mPaused;//生命周期暂停private boolean mClickPaused;//点击暂停
//    private boolean mVideoFileFromRecord;private ActionListener mActionListener;@Overrideprotected int getLayoutId() {return R.layout.dialog_active_video_preview;}@Overrideprotected int getDialogStyle() {return R.style.dialog2;}@Overrideprotected boolean canCancel() {return true;}@Overrideprotected void setWindowAttributes(Window window) {WindowManager.LayoutParams params = window.getAttributes();params.width = WindowManager.LayoutParams.MATCH_PARENT;params.height = WindowManager.LayoutParams.MATCH_PARENT;window.setAttributes(params);}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);findViewById(R.id.btn_close).setOnClickListener(this);findViewById(R.id.video_container).setOnClickListener(this);mPlayBtn = findViewById(R.id.btn_play);//暂停按钮动画mPlayBtnAnimator = ObjectAnimator.ofPropertyValuesHolder(mPlayBtn,PropertyValuesHolder.ofFloat("scaleX", 4f, 0.8f, 1f),PropertyValuesHolder.ofFloat("scaleY", 4f, 0.8f, 1f),PropertyValuesHolder.ofFloat("alpha", 0f, 1f));mPlayBtnAnimator.setDuration(150);mPlayBtnAnimator.setInterpolator(new AccelerateInterpolator());mTXCloudVideoView = findViewById(R.id.video_view);mPlayer = new TXVodPlayer(mContext);mPlayer.setConfig(new TXVodPlayConfig());mPlayer.setPlayerView(mTXCloudVideoView);mPlayer.enableHardwareDecode(false);mPlayer.setRenderRotation(TXLiveConstants.RENDER_ROTATION_PORTRAIT);mPlayer.setRenderMode(TXLiveConstants.RENDER_MODE_FULL_FILL_SCREEN);mPlayer.setPlayListener(this);Bundle bundle = getArguments();if (bundle != null) {mVideoPath = bundle.getString(VIDEO_PATH);if (!TextUtils.isEmpty(mVideoPath)) {
//                mVideoFileFromRecord = mVideoPath.contains(CommonAppConfig.VIDEO_PATH_RECORD);int result = mPlayer.startPlay(mVideoPath);if (result == 0) {mPlayStarted = true;}}}}@Overridepublic void onPlayEvent(int e, Bundle bundle) {switch (e) {case TXLiveConstants.PLAY_EVT_PLAY_END://播放结束onReplay();break;case TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION://onVideoSizeChanged(bundle.getInt("EVT_PARAM1", 0), bundle.getInt("EVT_PARAM2", 0));onVideoSizeChanged();break;}}@Overridepublic void onNetStatus(Bundle bundle) {}/*** 获取到视频宽高回调*/public void onVideoSizeChanged() {double videoWidth = 0;double videoHeight = 0;MediaMetadataRetriever mmr = null;try {mmr = new MediaMetadataRetriever();mmr.setDataSource(mVideoPath);String width = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);//宽String height = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);//高String rotation = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);if ("0".equals(rotation)) {if (!TextUtils.isEmpty(width)) {videoWidth = Double.parseDouble(width);}if (!TextUtils.isEmpty(height)) {videoHeight = Double.parseDouble(height);}} else {if (!TextUtils.isEmpty(height)) {videoWidth = Double.parseDouble(height);}if (!TextUtils.isEmpty(width)) {videoHeight = Double.parseDouble(width);}}} catch (Exception e) {e.printStackTrace();} finally {if (mmr != null) {mmr.release();}}if (mTXCloudVideoView != null && videoWidth > 0 && videoHeight > 0) {FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mTXCloudVideoView.getLayoutParams();if (videoWidth / videoHeight > 0.5625f) {//横屏 9:16=0.5625params.height = (int) (mTXCloudVideoView.getWidth() / videoWidth * videoHeight);params.gravity = Gravity.CENTER;mTXCloudVideoView.requestLayout();}}}/*** 获取到视频宽高回调*/public void onVideoSizeChanged(float videoWidth, float videoHeight) {if (mTXCloudVideoView != null && videoWidth > 0 && videoHeight > 0) {FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) mTXCloudVideoView.getLayoutParams();if (videoWidth / videoHeight > 0.5625f) {//横屏 9:16=0.5625params.height = (int) (mTXCloudVideoView.getWidth() / videoWidth * videoHeight);params.gravity = Gravity.CENTER;mTXCloudVideoView.requestLayout();}}}/*** 显示开始播放按钮*/private void showPlayBtn() {if (mPlayBtn != null && mPlayBtn.getVisibility() != View.VISIBLE) {mPlayBtn.setVisibility(View.VISIBLE);}}/*** 隐藏开始播放按钮*/private void hidePlayBtn() {if (mPlayBtn != null && mPlayBtn.getVisibility() == View.VISIBLE) {mPlayBtn.setVisibility(View.INVISIBLE);}}/*** 点击切换播放和暂停*/private void clickTogglePlay() {if (!mPlayStarted) {return;}if (mPlayer != null) {if (mClickPaused) {mPlayer.resume();} else {mPlayer.pause();}}mClickPaused = !mClickPaused;if (mClickPaused) {showPlayBtn();if (mPlayBtnAnimator != null) {mPlayBtnAnimator.start();}} else {hidePlayBtn();}}@Overridepublic void onPause() {super.onPause();mPaused = true;if (!mClickPaused && mPlayer != null) {mPlayer.pause();}}@Overridepublic void onResume() {super.onResume();if (mPaused) {if (!mClickPaused && mPlayer != null) {mPlayer.resume();}}mPaused = false;}/*** 循环播放*/private void onReplay() {if (mPlayStarted && mPlayer != null) {mPlayer.seek(0);mPlayer.resume();}}@Overridepublic void onClick(View v) {int i = v.getId();if (i == R.id.btn_close) {dismiss();} else if (i == R.id.video_container) {clickTogglePlay();}}@Overridepublic void onDestroy() {if (mPlayer != null) {mPlayer.stopPlay(false);mPlayer.setPlayListener(null);}mContext = null;mPlayer = null;mActionListener = null;super.onDestroy();}public void setActionListener(ActionListener actionListener) {mActionListener = actionListener;}public interface ActionListener {void onDeleteClick();}}
四、项目demo源码结构图:

在这里插入图片描述有问题或者需要完整源码的私信我

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/444213.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

渗透测试 之 域渗透手法【域内用户枚举】手法 Kerbrute msf pyKerbrute 工具使用详解

说明一下: 域内用户枚举工具使用说说: Kerbrute pyKerbrute MSF模块的使用 域内用户名枚举原理分析: 域内用户枚举攻击防御: 流量检测: 日志层面: 说明一下: 域环境或者内网环境下,可以在没有域环…

npm ERR! PhantomJS not found on PATH

安装phantomj时发生报错 old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. npm ERR! code 1 npm ERR! path /va…

四、Spring Boot集成Spring Security之认证流程

Spring Boot集成Spring Security之认证流程 一、概要说明二、基于内存的用户名密码1、默认用户名密码2、自定义用户名密码3、为方便测试添加测试接口TestController 三、登录登出重要概念介绍四、登录业务逻辑1、登录业务相关过滤器2、访问业务请求处理流程①、访问业务请求地址…

kubernetes中微服务部署

微服务 问:用控制器来完成集群的工作负载,那么应用如何暴漏出去? 答:需要通过微服务暴漏出去后才能被访问 Service 是一组提供相同服务的Pod对外开放的接口借助Service,应用可以实现服务发现和负载均衡Service 默认只…

初学Qt之环境安装与 hello word

环境: Qt Creator 4.11.0 (Community) Qt 5.14.0 目录 1.Qt环境配置 1.1 下载Qt 5.14.0 1.2 注册Qt账号 1.3 安装Qt 1.4 配置环境变量 2.创建项目 2.1 创建一个项目 2.2 初始代码解析 2.3 可视化GUI ​编辑 2.4 hello word 2.4.1 可视化hello word …

链式二叉树及二叉树各种接口的实现(C)

二叉树的性质 若规定根节点的层数为1,则一棵非空二叉树的第 i i i层上最多有 2 i − 1 2^{i-1} 2i−1个结点.若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 2 h − 1 2^{h}-1 2h−1对任何一棵二叉树,如果度为0其叶结点个数为 n 0 …

Koa学习

Koa 安装与配置 1. 初始化项目 在终端中执行以下命令: # 创建项目文件夹 mkdir koa cd koa# 初始化并安装依赖 npm init -y npm install koa npm install nodemon --save-dev2. 修改 package.json 在 package.json 文件中进行如下修改: {"type…

C语言 | Leetcode C语言题解之第472题连接词

题目&#xff1a; 题解&#xff1a; typedef struct Trie {struct Trie * children[26];bool isEnd; }Trie;#define TRIE_INITIAL(node) do { \for (int i 0; i < 26; i) { \(node)->children[i] NULL; \} \(node)->isEnd false; \ }while(0);static void freeTri…

互联网线上融合上门洗衣洗鞋小程序,让洗衣洗鞋像点外卖一样简单

随着服务创新的风潮&#xff0c;众多商家已巧妙融入预约上门洗鞋新风尚&#xff0c;并携手洗鞋小程序&#xff0c;开辟线上蓝海。那么&#xff0c;这不仅仅是一个小程序&#xff0c;它究竟蕴含着哪些诱人好处呢&#xff1f; 1. 无缝融合&#xff0c;双线共赢&#xff1a;小程序…

美团Java一面

美团Java一面 9.24一面&#xff0c;已经寄了 收到的第一个面试&#xff0c;表现很不好 spring bean生命周期 作用域&#xff08;忘完了&#xff09; 为什么用redis缓存 redis和数据库的缓存一致性问题 redis集群下缓存更新不一致问题 aop说一下 arraylist和linkedlist 数据库的…

2024年软件设计师中级(软考中级)详细笔记【5】软件工程基础知识上(分值10+)

第5章软件工程 目录 前言第5章 软件工程基础知识&#xff08;上&#xff09;&#xff08;分值10&#xff09;5.1 软件工程概述5.1.4 软件过程 5.2 软件过程模型5.2.1 瀑布模型 (Waterfall Model)5.2.2 增量模型5.2.3 演化模型5.2.4 喷泉模型&#xff08;Water Fountain Model&a…

JavaScript下载文件(简单模式、跨域问题、文件压缩)

文章目录 简介简单文件下载通过模拟form表单提交通过XMLHttpRequest方式 跨域(oss)下载并压缩文件完整示例文件压缩跨域设置 简介 相信各位开发朋友都遇到过下载的文件的需求&#xff0c;有的非常简单&#xff0c;基本链接的形式就可以。 有的就比较复杂&#xff0c;涉及跨域…

小米路由器R3Gv2安装openwrt记录

前言 小米路由器R3Gv2的硬件配置与小米路由器4A千兆版一致&#xff0c;但bootloader有所不同&#xff0c;因此openwrt的固件不要互刷。另外&#xff0c;R3Gv2和R3G、4A百兆版是不同的设备&#xff0c;切勿混淆。 硬件信息 OpenWrt参数页-Xiaomi MiWiFi 3G v2 CPU&#xff1a…

PPT分享:埃森哲-业务流程BPM能力框架体系

PPT下载链接见文末~ 业务流程管理&#xff08;BPM, Business Process Management&#xff09;的能力框架体系是一个全面、系统的流程管理方法论和工具集&#xff0c;旨在帮助企业优化和持续改进其业务流程&#xff0c;从而提升运营效率和市场竞争力。 一、BPM能力框架体系概述…

CUDA Example 处理一张二维图像

CUDA 实战 5.3.3 基于共享内存的位图&#xff1a;突出了同步操作的重要性 __synthreads() 才能保证图像的正确输出&#xff0c;如果去掉同步操作&#xff0c;输出图像如下&#xff1a; 加上同步操作之后&#xff1a; #include "cpu_bitmap.h" #include "cpu_an…

小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(初级)

前言 哈喽哈喽友友们,这里是zyll~(小北)智慧龙阁的创始人及核心技术开发者。在技术的广阔天地里,我专注于大数据与全栈开发,并致力于成为这一领域的新锐力量。通过智慧龙阁这个平台,我期望能与大家分享我的技术心得,共同探索技术的无限可能。 Ascend C编程:小北的技术…

SKG未来健康校招社招入职测评:综合能力及性格问卷SHL测评题库

SKG未来健康科技股份有限公司在校招和社招过程中使用的SHL测评题库主要考察应聘者的综合能力和性格特征。以下是对这些测评的简要分析&#xff1a; 综合能力测评&#xff1a; 测评时间&#xff1a;46分钟&#xff08;实际答题时间36分钟&#xff09; 题目数量&#xff1a;30题…

【操作系统】深入探索:操作系统内核与用户进程的数据交互艺术

目录 一、数据从内核缓冲区拷贝到用户进程缓冲区&#xff0c;是谁来负责拷贝的&#xff0c;是操作系统还是用户进程&#xff1f;实际的执行者到底是谁&#xff1f;二、系统调用以及用户态内核态的相互转换1、系统调用2、用户态内核态的相互转换 三、如何形象的理解linux的虚拟地…

Django学习笔记十三:优秀案例学习

Django CMS 是一个基于 Django 框架的开源内容管理系统&#xff0c;它允许开发者轻松地创建和管理网站内容。Django CMS 提供了一个易于使用的界面来实现动态网站的快速开发&#xff0c;并且具有丰富的内容管理功能和多种插件扩展。以下是 Django CMS 的一些核心特性和如何开始…

Vue 脚手架学习

1.使用 Vue 脚手架 1.1 初始化脚手架 1.1.1 具体步骤 第一步&#xff08;仅第一次执行&#xff09;&#xff1a;全局安装vue/cli。 npm install -g vue/cli 第二步&#xff1a;切换到你要创建项目的目录&#xff0c;然后使用命令创建项目 vue create xxxx 第三步&#xff1a;启…