安卓: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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        init();
        mVideoRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public 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() {
        // 添加网络视频的url
        mUrlList = 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;
        }
    }


    @Override
    protected 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
    @Override
    public VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new VideoViewHolder(LayoutInflater.from(context).inflate(R.layout.video_page,
                parent, false));
    }



    @Override
    public 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);
    }

    @Override
    public 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">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <androidx.recyclerview.widget.RecyclerView
            android: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.JzvdStd
        android: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.mfbz.cn/a/52704.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

iOS 应用上架流程详解

iOS 应用上架流程详解 欢迎来到我的博客&#xff0c;今天我将为大家分享 iOS 应用上架的详细流程。在这个数字化时代&#xff0c;移动应用已经成为了人们生活中不可或缺的一部分&#xff0c;而 iOS 平台的 App Store 则是开发者们发布应用的主要渠道之一。因此&#xff0c;了解…

2024考研408-计算机网络 第一章-计算机网络体系结构学习笔记

文章目录 前言一、计算机网络概述1.1、概念及功能1.1.1、计算机网络的概念1.1.2、计算机网络的功能功能1、数据通信功能2、资源共享功能3、分布式处理功能4、提高可靠性&#xff08;分布式处理引申功能&#xff09;功能5、负载均衡&#xff08;也是分布式处理引申功能&#xff…

机器学习的关键词和算法总结

随着全球各行业的数据治理、数字化转型智能化辅助的引入发展&#xff0c;机器学习&#xff08;包括深度学习&#xff09;在逐步深入到各行各业&#xff0c;所以&#xff0c;有必要对机器学习的常见术语&#xff0c;经典算法及应用场景进行一次总结&#xff0c;其实机器学习兴起…

Java Design and development -- QQ chat

About ARTS - Complete one ARTS per week: ● Algorithm: Do at least one LeetCode algorithm per week Review: Read and comment on at least one technical article in English ● Tips: Learn at least one technical trick ● Share: Share a technical article with op…

基于新浪微博海量用户行为数据、博文数据数据分析:包括综合指数、移动指数、PC指数三个指数

基于新浪微博海量用户行为数据、博文数据数据分析&#xff1a;包括综合指数、移动指数、PC指数三个指数 项目介绍 微指数是基于海量用户行为数据、博文数据&#xff0c;采用科学计算方法统计得出的反映不同事件领域发展状况的指数产品。微指数对于收录的关键词&#xff0c;在指…

指针应用基础练习

&#xff08;1&#xff09;一级指针&#xff0c;二级指针 void getString(char **p) {*p "hello world"; }int main(void) {char *str NULL;getString(&str);printf("%s\n", str); } 代码分析&#xff1a; 定义了一个char型指针str&#xff0c;…

Vue 3:玩一下web前端技术(五)

前言 本章内容为VUE语法的简单学习与相关语法讨论。 上一篇文章地址&#xff1a; Vue 3&#xff1a;玩一下web前端技术&#xff08;四&#xff09;_Lion King的博客-CSDN博客 下一篇文章地址&#xff1a; Vue 3&#xff1a;玩一下web前端技术&#xff08;六&#xff09;_L…

复习之linux存储的基本管理

一、实验环境的设定 1. 实验环境的搭建 本节内容只需要一台虚拟机 westosa reset重置虚拟机&#xff0c;保证实验环境的纯净配置网络实现ssh连接 重置虚拟机后&#xff0c;配置网络&#xff0c;设定ip&#xff1a;172.25.254.100&#xff0c;保证与主机可以通信 实现ssh连接…

chatgpt 接口使用(一)

使用api实现功能 参考链接&#xff1a;https://platform.openai.com/examples 安装库&#xff1a; pip3 install openai 例如&#xff1a; import os import openaiopenai.api_key os.getenv("OPENAI_API_KEY") response openai.ChatCompletion.create(model&q…

配置tomcat内存大小(windows、linux)

一、参数说明 -Xms&#xff1a; JVM初始分配的堆内存 -Xmx&#xff1a; JVM最大允许分配的堆内存&#xff0c;按需分配 -XX:PermSize&#xff1a; JVM初始分配的非堆内存 -XX:MaxPermSize&#xff1a; JVM最…

QT服务器练习

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTcpServer(this); }Widget::~Widget() {delete ui; }//启动服务器按钮对…

阿里云域名备案

最好的爱情&#xff0c;不是因为我们彼此需要在一起&#xff0c;而是因为我们彼此想要在一起。 阿里云的域名如何备案&#xff0c;域名备案和ICP备案一样吗&#xff1f;&#xff1f; 截至我所掌握的知识&#xff08;2021年9月&#xff09;&#xff0c;阿里云的域名备案和ICP备案…

什么是嵌入式软件开发?

嵌入式软件一般是在交叉的开发环境下进行的&#xff0c;这样的运行环境能够让软件开发过程中更加稳定、可靠和安全&#xff0c;在很大程度上提升了软件开发的质量和效率&#xff0c;同时也使得软件开发的难度和程度大大降低。 嵌入式软件的交叉开发环境&#xff0c;反映了用于…

Spire.Office for.NET Crack

Spire.Office for.NET Crack Spire.Office for.NET是E-iceblue提供的企业级Office.NET API的组合。它包括Spire.Doc、Spire.XLS、Spire.Seadsheet、Spire.Presentation、Spire_PDF、Spire.DataExport、SpireOfficeViewer、Spire-PDFViewer、Spire.DocViewer、Spire.Barcode和Sp…

windows版docker部署springcloud项目

材料&#xff1a; 1.windows版docker环境&#xff08;其他版教程可能道理一样但是比如文件后坠名上可能有差异&#xff09; 2.运行好的数据库容器&#xff08;实现教程&#xff09; 3.所有jar包 实现&#xff1a; 最后整好的文件夹结构图&#xff08;原工程文件机密&#xf…

【Git】git reset 版本回退 git rm

前言 在日常开发时&#xff0c;我们经常会需要撤销之前的一些修改内容或者回退到之前的某一个版本&#xff0c;这时候reset命令就派上用场了 git reset 用法1——所有文件回退到某个版本 1、使用git reflog查看要回退的commit对象 2、使用git reset [-- hard/soft /mixed] …

【Linux后端服务器开发】IP协议

目录 一、IP协议概述 二、协议头格式 三、网段划分 四、IP地址的数量限制 五、路由 六、分片和组装 一、IP协议概述 主机&#xff1a;配有IP地址&#xff0c;但是不进行路由控制的设备 路由器&#xff1a;即配有IP地址&#xff0c;又能进行路由控制 节点&#xff1a;主…

application.yml 或 application.properties 配置文件乱码问题

一、idea写application.yml配置文件&#xff0c; 用到了中文注释&#xff0c;写的时候好好地&#xff0c;但是运行项目后&#xff0c;出现乱码情况&#xff0c;如下&#xff1a; 二、解决方法 将文件编码方式 设置成UTF-8即可 File-Setting-Editor-File Encodings 再次运行项…

【《React Hooks实战》——指导你使用hook开发性能优秀可复用性高的React组件】

使用React Hooks后&#xff0c;你很快就会发现&#xff0c;代码变得更具有组织性且更易于维护。React Hooks是旨在为用户提供跨组件的重用功能和共享功能的JavaScript函数。利用React Hooks&#xff0c; 可以将组件分成多个函数、管理状态和副作用&#xff0c;并且不必声明类即…

FreeRTOS源码分析-7 消息队列

目录 1 消息队列的概念和作用 2 应用 2.1功能需求 2.2接口函数API 2.3 功能实现 3 消息队列源码分析 3.1消息队列控制块 3.2消息队列创建 3.3消息队列删除 3.4消息队列在任务中发送 3.5消息队列在中断中发送 3.6消息队列在任务中接收 3.7消息队列在中断中接收 1 消…