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.mzph.cn/web/54779.shtml

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

相关文章

wordpress调用全部页面 排除某个指定ID页面

要在WordPress中调用所有页面并排除指定的ID&#xff0c;您可以使用WP_Query类。以下是一个示例代码&#xff0c;它将查询所有页面并排除指定的页面ID&#xff1a; <?php // Page ID array to exclude $exclude_ids array( 6, 66, 666 ); //Replace here with the page I…

数据要素资料阅读笔记

目录 文章目录 目录数据价值化与数据要素市场发展报告 2024 —— 国信息通信研究院政策与经济研究所一、新理论:数据要素价值释放的经济学分析(一)从稀缺性看数据要素特征(二)数据要素市场化配置理论(三)数据要素市场分类及特征(四)数据要素价值释放路径和框架二、新进展:数据价…

(Linux和数据库)1.Linux操作系统和常用命令

了解Linux操作系统介绍 除了办公和玩游戏之外不用Linux&#xff0c;其他地方都要使用Linux&#xff08;it相关&#xff09; iOS的本质是unix&#xff08;unix是付费版本的操作系统&#xff09; unix和Linux之间很相似 Linux文件系统和目录 bin目录--放工具使用的 操作Linux远程…

CentOS 7 上安装 Kibana

以下是在 CentOS 7 上安装 Kibana 的步骤&#xff1a; 一、安装 Java&#xff08;如果尚未安装&#xff09; Kibana 需要 Java 运行环境。如果系统中没有安装 Java&#xff0c;可以使用以下命令安装 OpenJDK&#xff1a; sudo yum install java-1.8.0-openjdk二、添加 Elast…

消费者Rebalance机制

优质博文&#xff1a;IT-BLOG-CN 一、消费者Rebalance机制 在Apache Kafka中&#xff0c;消费者组 Consumer Group会在以下几种情况下发生重新平衡Rebalance&#xff1a; 【1】消费者加入或离开消费者组&#xff1a; 当一个新的消费者加入消费者组或一个现有的消费者离开消费…

ROS基础入门——实操教程

ROS基础入门——实操教程 前言 本教程实操为主&#xff0c;少说书。可供参考的文档中详细的记录了ROS的实操和理论&#xff0c;只是过于详细繁杂了&#xff0c;看得脑壳疼&#xff0c;于是做了这个笔记。 Ruby Rose&#xff0c;放在这里相当合理 本文初编辑于2024年10月4日 C…

mysql linux 安装

--------------------------------------------------------------------------------------------------------------------------------- 1.前置准备 1.1 卸载旧版MySQL 1.2 查看rpm包 rpm -qa|grep mysql 若有可用 rpm -e 安装包 --nodeps 1.3 查找mysql残留包&#x…

MySQL--事务(详解)

目录 一、前言二、本文章目标三、什么是事务&#xff1f;四、事务的ACID特性五、为什么要使用事务六、如何使用事务6.1 查看支持使用事务的引擎6.2语法6.3 开启⼀个事务&#xff0c;执行更新后回滚6.4 开启一个事务更新后提交6.5 保存点6.6 自动/手动提交事务 七、事务的隔离性…

Spring异步线程池的问题

今天看一视频&#xff0c;提到说 Spring默认的异步线程池比较简单&#xff0c;每次执行异步任务&#xff0c;都会新建一个线程进行处理&#xff0c;不会重复利用&#xff0c;所以在用Spring框架开发的时候&#xff0c;需要自定义异步线程池。第一次听到这个说法。遂开始百度。 …

Word页眉内容自动填充为章节标题

Word页眉内容自动填充为章节标题 在写毕业论文的过程中&#xff0c;通常要求将页眉设置为章节标题&#xff0c;例如这样 通常&#xff0c;页眉内容我们都是手敲上去的&#xff0c;其实在Word中可以设置为自动引用章节标题&#xff0c;以下为设置方法&#xff0c;仅供参考&…

JVM错误:OutOfMemoryError: GC overhead limit exceeded

OutOfMemoryError: GC overhead limit exceeded 在Window服务器上跑一个项目&#xff0c;无意中出现服务访问不了&#xff0c;查看日志文档&#xff0c;第一次遇到了这个异常信息。 1. 错误含义 OutOfMemoryError: GC overhead limit exceeded 是 JVM 中的一种错误&#xff…

jmeter入门:脚本录制

1.设置代理。 网络连接-》代理-》手动设置代理. ip&#xff1a; 127.0.0.1&#xff0c; port&#xff1a;8888 2. add thread group 3. add HTTP(s) test script recorder, target controller chooses Test plan-> thread Group 4. click start. then open the browser …

鸡兔同笼,但是线性代数

灵感来自&#xff1a;bilibili&#xff0c;巨佬&#xff01; 我们有 14 14 14 个头&#xff0c; 32 32 32 只脚&#xff0c;所有鸡和兔都没有变异&#xff0c;头和脚都完整&#xff0c;没有数错。还有什么 Bug 吗 小学奥数 假设全是鸡&#xff0c;则有 14 2 28 14 \time…

【2024保研经验帖】东南大学计算机学院夏令营

前言 背景&#xff1a;末211&#xff0c;专业计算机科学与技术&#xff0c;rk前5%&#xff0c;无科研&#xff0c;只有几个竞赛 东南大学计算机学院夏令营需要老师推荐&#xff0c;一个老师的推荐名额感觉应该挺多的&#xff0c;因为学硕和专硕都进了两百多人&#xff0c;总共…

利用 Python 爬虫采集 1688商品详情

1688是中国的一个大型B2B电子商务平台&#xff0c;主要用于批发和采购各种商品。对于需要从1688上获取商品详情数据、工程数据或店铺数据的用户来说&#xff0c;可以采用以下几种常见的方法&#xff1a; 官方API接口&#xff1a;如果1688提供了官方的API接口&#xff0c;那么可…

猎板PCB设计中的HDI板技术革新与实践

在设计工业控制器的HDI板时&#xff0c;需要注意以下几个关键方面&#xff1a; 布线设计&#xff1a;由于HDI板布线密度高&#xff0c;合理规划走线非常关键&#xff0c;避免交叉和重叠&#xff0c;确保信号传输的稳定性和可靠性。需要控制线宽和线距&#xff0c;根据电路板的…

docker的安装与启动——配置国内Docker源

移除旧版本docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 配置docker yum源。 sudo yum install -y yum-utils sudo yum-config-manager –add-repo ht…

SAP_FI_表ACDOCA取代的表

在 SAP S/4HANA 系统中&#xff0c;ACDOCA&#xff08;通用分录表&#xff0c;Universal Journal&#xff09;引入了全新的数据结构&#xff0c;取代了原先 ERP 系统中多个财务和控制模块的表。ACDOCA 通过一个单一表格整合了财务会计&#xff08;FI&#xff09;和管理会计&…

C语言 | Leetcode C语言题解之第454题四数相加II

题目&#xff1a; 题解&#xff1a; struct hashTable {int key;int val;UT_hash_handle hh; };int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize) {struct hashTable* hashtable NULL;for (int i 0; i < ASize; i) {for (…

日语学习零基础生活日语口语柯桥外语学校|股票用日语怎么说?

在日语中&#xff0c;“股票”可以说&#xff1a; • 株&#xff08;かぶ&#xff09; 这是最常用的表达方式&#xff0c;直接表示“股票”。 例如&#xff1a; 株を買う - 买股票 株を売る - 卖股票 • 株式&#xff08;かぶしき&#xff09; 这个词也是“股票”的意…