安卓:JzvdStd——网络视频播放器

目录

一、JzvdStd介绍

JzvdStd的特点和功能:

 JzvdStd常用方法:

二、JzvdStd使用

1、补充知识:

例子:

MainActivity : 

VideoPageAdapter : 

activity_main: 

video_page: 

运行结果:

一、JzvdStd介绍

        JzvdStd是一个用于Android平台的开源视频播放器库,它提供了丰富的功能和易于使用的API,使开发者能够快速实现高质量的视频播放功能。

JzvdStd的特点和功能:

  • 支持常见的视频格式:JzvdStd支持播放各种常见的视频格式,包括MP4、FLV、MKV、AVI等。
  • 自定义界面:JzvdStd提供了丰富的界面定制选项,开发者可以根据自己的需求自定义播放器的外观和交互方式。
  • 全屏播放:JzvdStd支持全屏播放模式,用户可以轻松切换到全屏模式以获得更好的观看体验。
  • 手势操作:JzvdStd支持手势操作,用户可以通过滑动手势来调节音量、亮度和播放进度。
  • 弹幕功能:JzvdStd内置了弹幕功能,用户可以在视频播放过程中发送和接收弹幕信息。
  • 网络视频流支持:JzvdStd能够播放网络视频流,开发者可以通过URL链接直接播放在线视频。

 JzvdStd常用方法:

  • setVideoUrl(String url)设置要播放的视频源,可以是本地文件路径或网络视频地址。
  • startVideo()开始播放视频。
  • pauseVideo()暂停视频播放。
  • resumeVideo()恢复视频播放。
  • stopVideo()停止视频播放,并释放相关资源。
  • releaseAllVideos()释放所有正在播放的视频,可用于在切换页面或退出应用时释放资源。
  • enterFullScreen()进入全屏播放模式。
  • exitFullScreen()退出全屏播放模式。
  • setLoop(boolean loop)设置是否循环播放视频。
  • setScreenOnWhilePlaying(boolean screenOn)设置在视频播放期间是否保持屏幕亮起。
  • seekTo(int position)跳转到指定的播放位置。
  • getCurrentPosition()获取当前播放位置。
  • getDuration()获取视频总时长。
  • isPlaying()判断视频是否正在播放。
  • setOnJzvdStdListener(OnJzvdStdListener listener)设置JzvdStd的监听器,用于监听视频播放状态、全屏切换等事件。
  • setVideoImageDisplayType(JzvdStd.SCREEN_IMAGE_DISPLAY_TYPE type)设置视频封面图片的显示方式,包括填充、拉伸、原始比例等。
  • setVideoImage(String imageUrl):设置视频封面图片的URL地址。
  • setMediaInterface(JZMediaInterface mediaInterface)设置JzvdStd使用的媒体接口,可以自定义实现更多功能。

依赖包:

implementation 'cn.jzvd:jiaozivideoplayer:7.0.5'

二、JzvdStd使用

补充知识:

        PagerSnapHelper是一个辅助类,用于在 RecyclerView 中实现分页滚动效果。它可以与 RecyclerView 搭配使用,实现一次只显示一页内容,并在滚动停止时自动对齐到最近的一页。它可以提供更流畅、直观的滑动体验,并方便地实现横向或纵向的分页展示效果。

主要特点和用途如下:

  • 1. 分页滚动:PagerSnapHelper 可以使 RecyclerView 实现类似 ViewPager 的分页滚动效果,即一次只能滚动一页内容。当用户滚动 RecyclerView 时,它会自动将滚动停止的位置对齐到最近的一页。
  • 2. 对齐效果:PagerSnapHelper 可以确保 RecyclerView 停止滚动时,当前可见项完全对齐到 RecyclerView 的边界。这样可以让用户更清晰地看到每一页的内容,提供更好的视觉体验。
  • 3. 简单易用:PagerSnapHelper 是 Android Support Library 中提供的一个默认实现类,可以轻松地与 RecyclerView 集成使用。只需要创建一个 PagerSnapHelper 对象并调用attachToRecyclerView()方法来关联 RecyclerView,即可实现分页滚动效果。

使用 PagerSnapHelper 的步骤如下:

  • 1. 创建 PagerSnapHelper 对象:PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
  • 2. 关联 RecyclerView:pagerSnapHelper.attachToRecyclerView(recyclerView);,其中 recyclerView是你的 RecyclerView 对象。
  • 3. 根据需要设置 RecyclerView 的布局管理器(LinearLayoutManager、GridLayoutManager 等)和适配器,以及其他相应的配置。

例子:

MainActivity : 

package com.example.jzvdstddemo;import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SnapHelper;import android.os.Bundle;
import android.view.View;import java.util.ArrayList;
import java.util.List;import butterknife.BindView;
import butterknife.ButterKnife;
import cn.jzvd.JzvdStd;public class MainActivity extends AppCompatActivity {@BindView(R.id.main_recycler_view)RecyclerView mVideoRecyclerView;private List<String> mUrlList;private PagerSnapHelper mSnapHelper;private VideoPageAdapter mVideoPageAdapter;private LinearLayoutManager mLinearLayoutManager;private int currentPosition = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);init();mVideoRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);switch (newState) {case RecyclerView.SCROLL_STATE_IDLE://停止滚动playVideoInSnapPosition(recyclerView, mSnapHelper, mLinearLayoutManager);break;case RecyclerView.SCROLL_STATE_DRAGGING://拖动break;case RecyclerView.SCROLL_STATE_SETTLING://惯性滑动// 发生惯性滑动时停止播放任何正在播放的视频,并释放相关的资源。这可以防止在快速滑动过程中出现视频播放错乱或冲突的情况。JzvdStd.releaseAllVideos();break;}}});}private void init() {// 添加网络视频的urlmUrlList = new ArrayList<>();mUrlList.add("https://poss-videocloud.cns.com.cn/oss/2021/05/08/chinanews/MEIZI_YUNSHI/onair/25AFA3CA2F394DB38420CC0A44483E82.mp4");mUrlList.add("https://poss-videocloud.cns.com.cn/oss/2021/05/08/chinanews/MEIZI_YUNSHI/onair/25AFA3CA2F394DB38420CC0A44483E82.mp4");mUrlList.add("https://poss-videocloud.cns.com.cn/oss/2021/05/08/chinanews/MEIZI_YUNSHI/onair/25AFA3CA2F394DB38420CC0A44483E82.mp4");// HORIZONTAL横着滑动,VERTICAL竖着滑动mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);mVideoRecyclerView.setLayoutManager(mLinearLayoutManager);mSnapHelper = new PagerSnapHelper();mSnapHelper.attachToRecyclerView(mVideoRecyclerView);mVideoPageAdapter = new VideoPageAdapter(this, mUrlList);mVideoRecyclerView.setAdapter(mVideoPageAdapter);}private void playVideoInSnapPosition(RecyclerView recyclerView, SnapHelper snapHelper, LinearLayoutManager linearLayoutManager) {// 获取当前固定的视图View view = snapHelper.findSnapView(linearLayoutManager);if (view != null) {// 获取当前位置int position = recyclerView.getChildAdapterPosition(view);if (currentPosition != position) {// 如果切换到了新的固定视图JzvdStd.releaseAllVideos(); // 释放之前的资源(停止播放上一个视频)RecyclerView.ViewHolder viewHolder = recyclerView.getChildViewHolder(view);if (viewHolder instanceof VideoPageAdapter.VideoViewHolder) {// 开始播放视频((VideoPageAdapter.VideoViewHolder) viewHolder).jzVideo.startVideo();}}currentPosition = position;}}@Overrideprotected void onPause() {super.onPause();JzvdStd.releaseAllVideos();}
}

VideoPageAdapter : 

package com.example.jzvdstddemo;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import com.bumptech.glide.Glide;import java.util.List;import butterknife.BindView;
import butterknife.ButterKnife;
import cn.jzvd.JzvdStd;public class VideoPageAdapter extends RecyclerView.Adapter<VideoPageAdapter.VideoViewHolder> {private Context context;private List<String> mUrlList;public VideoPageAdapter(Context context, List<String> urlList) {this.context = context;this.mUrlList = urlList;}@NonNull@Overridepublic VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {return new VideoViewHolder(LayoutInflater.from(context).inflate(R.layout.video_page,parent, false));}@Overridepublic void onBindViewHolder(@NonNull VideoViewHolder holder, int position) {// 设置视频url和视频标题holder.jzVideo.setUp(mUrlList.get(position), "第"+ (position + 1)+"视频",JzvdStd.STATE_NORMAL);// 如果是第一个视频,就设置自动播放if (position==0){holder.jzVideo.startVideo();}// 添加视频封面Glide.with(context).load(mUrlList.get(position)).into(holder.jzVideo.thumbImageView);}@Overridepublic int getItemCount() {return mUrlList.size();}public static class VideoViewHolder extends RecyclerView.ViewHolder {@BindView(R.id.jzVideo)public JzvdStd jzVideo;public VideoViewHolder(@NonNull View itemView) {super(itemView);// 视图绑定ButterKnife.bind(this,itemView);}}}

activity_main: 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/main_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/></RelativeLayout></androidx.constraintlayout.widget.ConstraintLayout>

video_page: 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><cn.jzvd.JzvdStdandroid:id="@+id/jzVideo"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>

依赖: 

 implementation 'com.jakewharton:butterknife:10.2.3' // 添加此依赖annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3' // 添加此规则implementation 'cn.jzvd:jiaozivideoplayer:7.0.5'implementation 'com.github.bumptech.glide:glide:4.8.0'

运行结果:

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

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

相关文章

第十次CCF计算机软件能力认证

第一题&#xff1a;分蛋糕 小明今天生日&#xff0c;他有 n 块蛋糕要分给朋友们吃&#xff0c;这 n 块蛋糕&#xff08;编号为 1 到 n&#xff09;的重量分别为 a1,a2,…,an。 小明想分给每个朋友至少重量为 k 的蛋糕。 小明的朋友们已经排好队准备领蛋糕&#xff0c;对于每个朋…

Blazor前后端框架Known-V1.2.9

V1.2.9 Known是基于C#和Blazor开发的前后端分离快速开发框架&#xff0c;开箱即用&#xff0c;跨平台&#xff0c;一处代码&#xff0c;多处运行。 Gitee&#xff1a; https://gitee.com/known/KnownGithub&#xff1a;https://github.com/known/Known 概述 基于C#和Blazor…

UE4 unlua学习笔记

将这三个插件放入Plugins内并重新编译 创建一个BlueprintLibrary&#xff0c;声明一个全局函数 在这里声明路径 点击Create Lua Template 在Content的Script即可生成对应的lua文件打开它&#xff01; 显示以上lua代码 打印Hello Unlua 创建该UI&#xff0c;就会在创建UI的Con…

Flutter-基础Widget

Flutter页面-基础Widget 文章目录 Flutter页面-基础WidgetWidgetStateless WidgetStateful WidgetState生命周期 基础widget文本显示TextRichTextDefaultTextStyle 图片显示FlutterLogoIconImageIamge.assetImage.fileImage.networkImage.memory CircleAvatarFadeInImage 按钮R…

火山引擎DataLeap如何解决SLA治理难题(二):申报签署流程与复盘详解

申报签署流程详解 火山引擎DataLeap SLA保障的前提是先达成SLA协议。在SLA保障平台中&#xff0c;以 申报单签署的形式达成SLA协议。平台核心特点是 优化了SLA达成的流程&#xff0c;先通过 “系统卡点计算”减少待签署任务的数量&#xff0c;再通过 “SLA推荐计算”自动签署部…

【Linux】网络基础

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统网络编程 文章目录 一、协议初识和网络协议分层&#xff08;TCP/IP四层模型&#xff09;认识协议TCP/IP五层&#xff08;或四层&#xff09;模型 二、认识MAC地址和IP地址认识MAC地址认识IP地址认…

基于Java的闲置物品管理系统(源码+文档+数据库)

很多在校学生经常因为冲动或者因为图一时的新鲜,购买了很多可能只是偶尔用一下的物品&#xff0c;大量物品将会闲置&#xff0c;因此&#xff0c;构建一个资源共享平台&#xff0c;将会极大满足师院学生的需求,可以将其闲置物品挂在资源共享平台上让有需要的学生浏览&#xff0…

Linux【网络基础】数据链路层IP协议技术补充DNSDHCP

文章目录 一、数据链路层&#xff08;1&#xff09;数据链路层与网络层的关联&#xff08;2&#xff09;局域网通信原理&#xff08;3&#xff09;以太网协议&#xff08;4&#xff09;ARP协议 二、NAT协议三、NAPT协议四、ICMP协议五、DNS六、DHCP 一、数据链路层 &#xff0…

二、JVM-深入运行时数据区

深入运行时数据区 计算机体系结构 JVM的设计实际上遵循了遵循冯诺依曼计算机结构 CPU与内存交互图&#xff1a; 硬件一致性协议&#xff1a; MSI、MESI、MOSI、Synapse、Firely、DragonProtocol 摩尔定律 摩尔定律是由英特尔(Intel)创始人之一戈登摩尔(Gordon Moore)提出来…

配置GIt账号、配置公钥

1.设置账号和邮箱 打开终端输入以下命令&#xff1a; git config --global --unset-all user.name git config --global --unset-all user.email然后输入以下命令来设置新的账号和邮箱&#xff1a; git config --global user.name "your_username" git config --glo…

与“云”共舞,联想凌拓的新科技与新突破

伴随着数字经济的高速发展&#xff0c;IT信息技术在数字中国建设中起到的驱动和支撑作用也愈发凸显。特别是2023年人工智能和ChatGPT在全球的持续火爆&#xff0c;更是为整个IT产业注入了澎湃动力。那么面对日新月异的IT信息技术&#xff0c;再结合疫情之后截然不同的经济环境和…

效率提升丨大学必看校园安全实用技巧

在当今社会&#xff0c;教育是培养人才、传承文明的重要场所。然而&#xff0c;教学楼作为学生、教师和员工活动的核心区域&#xff0c;也存在着潜在的安全隐患&#xff0c;其中最为突出的风险之一是火灾。火灾不仅危及生命财产&#xff0c;还可能给整个学校带来不可估量的损失…

vue3中使用原始标签制作一个拖拽和点击上传组件上传成功后展示

在Vue3中&#xff0c;可以使用<input type"file">标签来实现上传文件的功能&#xff0c;同时可以通过<div>标签来实现拖拽上传的功能。 首先&#xff0c;在template中定义一个包含<input>和<div>标签的组件&#xff1a; <template>&…

【C++】模板学习(二)

模板学习 非类型模板参数模板特化函数模板特化类模板特化全特化偏特化 模板分离编译模板总结 非类型模板参数 模板参数除了类型形参&#xff0c;还可以是非类型的形参。 非类型形参要求用一个常量作为类(函数)模板的一个参数。这个参数必须是整形家族的。浮点数&#xff0c;字…

pytorch学习——正则化技术——丢弃法(dropout)

一、概念介绍 在多层感知机&#xff08;MLP&#xff09;中&#xff0c;丢弃法&#xff08;Dropout&#xff09;是一种常用的正则化技术&#xff0c;旨在防止过拟合。&#xff08;效果一般比前面的权重衰退好&#xff09; 在丢弃法中&#xff0c;随机选择一部分神经元并将其输出…

Vue 常用指令 v-model 双向数据绑定

之前的指令&#xff0c;无论使用哪一种&#xff0c;都是在代码当中定义的内容。在web开发当中经常要去获取用户的输入&#xff0c;v-model可以十分方便的将表单的值和实例当中的数据关联起来。 这样就可以十分便捷的获取和设置表单元素的值了。&#xff08;注意是表单元素&…

SpringBoot第29讲:SpringBoot集成MySQL - MyBatis-Plus代码自动生成

SpringBoot第29讲&#xff1a;SpringBoot集成MySQL - MyBatis-Plus代码自动生成 本文是SpringBoot第29讲&#xff0c;主要介绍 MyBatis-Plus代码自动生成&#xff0c;以及产生此类代码生成工具的背景和此类工具的基本实现原理。 文章目录 SpringBoot第29讲&#xff1a;SpringBo…

【Linux】Centos7 的 Systemctl 与 创建系统服务 (shell脚本)

Systemctl systemctl 命令 # 启动 systemctl start NAME.service # 停止 systemctl stop NAME.service # 重启 systemctl restart NAME.service # 查看状态 systemctl status NAME.service # 查看所有激活系统服务 systemctl list-units -t service # 查看所有系统服务 syste…

PHP高级检索功能的实现以及动态拼接sql

我们学习了解了这么多关于PHP的知识&#xff0c;不知道你们对PHP高级检索功能的实现以及动态拼接sql是否已经完全掌握了呢&#xff0c;如果没有&#xff0c;那就跟随本篇文章一起继续学习吧! PHP高级检索功能的实现以及动态拼接sql。完成的功能有&#xff1a;可以单独根据一个…