YY播放器使用Flutter编写的一个聚合播放器, 起因是看了 ZY-Player的源码, 发现实现挺有意思的, 也比较简单

地址: https://github.com/waifu-project/movie

下载源码之后, 首先从入口函数入手

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await XHttp.init();
await GetStorage.init();
await MirrorManage.init();
final localStorage = GetStorage(); bool isDark = (localStorage.read(ConstDart.ls_isDark) ?? false);
bool systemBrightnessFlag = (localStorage.read(ConstDart.auto_dark) ?? false); Brightness wrapperIfDark = Brightness.light; {
if (isDark) wrapperIfDark = Brightness.dark;
if (GetPlatform.isWindows && systemBrightnessFlag) {
var windowMode = getWindowsThemeMode();
wrapperIfDark = windowMode;
} if (GetPlatform.isDesktop) {
doWhenWindowReady(() {
final initialSize = Size(990, 720);
appWindow.minSize = initialSize;
appWindow.size = initialSize;
appWindow.alignment = Alignment.center;
appWindow.show();
});
}
}

大概可以看出支持了 windows 平台(从 doWhenWindowReady 回调可以看出)

继续从依赖中猜一下大概实现方式

dependencies:
cupertino_icons: ^1.0.2 # 图标
get: 4.3.8 # 状态管理
salomon_bottom_bar: ^3.1.0
dio: ^4.0.0 # 网络库
cookie_jar: ^3.0.1
dio_cookie_manager: ^2.0.0
html: ^0.15.0
flutter_cupertino_settings: ^0.5.0
webview_flutter: ^2.1.1 # webview组件
flappy_search_bar_ns: ^2.0.2
xml2json: ^5.3.1 # xml to json
modal_bottom_sheet: ^2.0.0
pull_to_refresh: ^2.0.0
cupertino_list_tile: ^0.2.0
cached_network_image: ^3.1.0
chewie: ^1.2.2 # 视频播放
video_player: ^2.2.5
get_storage: ^2.0.3
path_provider: ^2.0.6
flutter_html: ^2.1.5
clipboard: ^0.1.3
wakelock: ^0.5.6
auto_orientation: ^2.1.0
desktop_webview_window: ^0.0.5
bitsdojo_window: ^0.1.1+1
url_launcher: ^6.0.12

首先是所谓的聚合实现

lib/impl/movie.dart中有一个抽象类

abstract class MovieImpl {

  /// 源信息
MovieMetaData get meta; /// 获取首页
Future<List<MirrorOnceItemSerialize>> getHome({
int page = 1,
int limit = 10,
}); /// 搜索
Future<List<MirrorOnceItemSerialize>> getSearch({
required String keyword,
int page = 1,
int limit = 10,
}); /// 获取视频详情
Future<MirrorOnceItemSerialize> getDetail(String movie_id);
}

基本上源的操作就那几个:

  • 首页
  • 搜索
  • 详情

接下来在看一下 MirrorOnceItemSerialize, 就是定义的一个标准实体类

class MirrorOnceItemSerialize {
/// id
final String id;
/// 标题
final String title;
/// 介绍
final String desc;
/// 喜欢
final int likeCount;
/// 访问人数
final int viewCount;
/// 不喜欢
final int dislikeCount;
/// 小封面图(必须要有)
final String smallCoverImage;
/// 大封面图
final String bigCoverImage;
/// 视频列表
final List<MirrorSerializeVideoInfo> videos;
/// 视频信息
/// 视频尺寸大小
/// 视频长度大小
final MirrorSerializeVideoSize videoInfo;
}

接下来就是实现这个抽象类, 比如内置的奈菲源, 来看一下其的实现方式

@override
Future<MirrorOnceItemSerialize> getDetail(String movie_id) async {
var detailURL = createURL(path: "/detail/" + movie_id);
var resp = await XHttp.dio.get(
detailURL,
options: Options(
headers: header,
),
);
var parse = html.parse(resp.data);
var ele = parse.querySelector(".myui-panel_hd");
if (ele == null) throw UnimplementedError();
var mirrorList = ele.querySelectorAll('li');
List<fetchMovieFrameURL> frames = [];
mirrorList.map((e) {
// ...(忽略代码)
return bat;
}).toList();
var data = await Future.wait<MirrorSerializeVideoInfo>(frames.map(
(e) async {
var url = await findIframeM3u8URL(e.id);
var title = e.title;
var item = MirrorSerializeVideoInfo(
url: url,
type: KBaseMirrorMovie.easyGetVideoType(url),
name: title,
);
return item;
},
).toList());
var infoEle = parse.querySelector(
'.myui-vodlist__thumb.img-md-220.img-xs-130.picture',
);
var coverImage = infoEle!.querySelector("img")?.attributes['data-original'] ?? "";
var title = infoEle.attributes['title'] ?? "";
return MirrorOnceItemSerialize(
id: movie_id,
smallCoverImage: coverImage,
title: title,
videos: data,
);
}

相信同学们基本上看明白了: 这个奈菲源的实现是通过解析 html 然后拿到数据

所以说, 只要你实现了视频源抽象类, 你想怎么玩就怎么玩(所以快来PR添加资源吧)

同样的, 根据这个抽象类, 实现了 ZY-Player 的源, 单个资源数据类型

{
"key": "快播云",
"id": 1,
"name": "快播云",
"api": "http://www.kuaibozy.com/api.php/provide/vod/from/kbm3u8/at/xml/",
"download": "",
"jiexiUrl": "https://jx.7kjx.com/?url=",
"group": "默认",
"isActive": true,
"status": "可用",
"reverseOrder": true
}

继续扒一下 ZF-Player的源码: https://github.com/cuiocean/ZY-Player/blob/master/src/lib/site/tools.js

就可以找到规则:

首页就是: $ROOT?ac=videolist&pg=${pg}

  /**
* 获取资源列表
* @param {*} key 资源网 key
* @param {number} [pg=1] 翻页 page
* @param {*} t 分类 type
* @returns
*/
list (key, pg = 1, t) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
let url = null
if (t) {
url = `${site.api}?ac=videolist&t=${t}&pg=${pg}`
} else {
url = `${site.api}?ac=videolist&pg=${pg}`
}
// todo
})
})
},

详情就是: $ROOT?ac=videolist&ids=${id}

/**
* 获取资源详情
* @param {*} key 资源网 key
* @param {*} id 资源唯一标识符 id
* @returns
*/
detail (key, id) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const url = `${res.api}?ac=videolist&ids=${id}`
// TODO
})
}

搜索就是: $ROOT?wd=${wd}

/**
* 搜索资源
* @param {*} key 资源网 key
* @param {*} wd 搜索关键字
* @returns
*/
search (key, wd) {
return new Promise((resolve, reject) => {
this.getSite(key).then(res => {
const site = res
const url = `${site.api}?wd=${encodeURI(wd)}`
// TODO
})
})
}

根据此规则就可以兼容 ZY-Player 的资源

后续

大概实现方式这样, 比较简单, 后续加一点点细节就可以了

有兴趣的同学可以看一下源码: https://github.com/waifu-project/movie

mail: chenhonzhou@gmail.com

YY播放器源码解析的更多相关文章

  1. 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  2. Android音乐播放器源码(歌词.均衡器.收藏.qq5.0菜单.通知)

    一款Android音乐播放器源码,基本功能都实现了 qq5.0菜单(歌词.均衡器.收藏.qq5.0菜单.通知) 只有向右滑动出现,菜单键和指定按钮都还没有添加. 源码下载:http://code.66 ...

  3. 一款非常简单的android音乐播放器源码分享给大家

    一款非常简单的android音乐播放器源码分享给大家,该应用虽然很小,大家常用的播放器功能基本实现了,可能有点还不够完善,大家也可以自己完善一下,源码在源码天堂那里已经有了,大家可以到那里下载学习吧. ...

  4. 一步步实现windows版ijkplayer系列文章之三——Ijkplayer播放器源码分析之音视频输出——音频篇

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  5. springMVC 拦截器源码解析

    前言:这两天学习了代理模式,自然想到了 springmvc 的 aop 使用的就是动态代理,拦截器使用的就是 jdk 的动态代理.今天看了看源码,记录一下.转载请注明出处:https://www.cn ...

  6. RestFramework之序列化器源码解析

    一.源码解析之序列化: 1.当视图类进行实例化序列化类做了如下操作: #ModelSerializer继承Serializer再继承BaseSerializer(此类定义实例化方法) #在BaseSe ...

  7. 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

    作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...

  8. 项目源码--Android3D影音播放器源码

      下载源码   技术要点: 1.本地音乐管理 2.音频流的解码 3. UI控件的综合使用 4. 视频流的解码 5. 动态更换皮肤 6. 3D效果的实现 7. 源码带详细的中文注释 ...... 详细 ...

  9. 实例源码--Android简单音乐播放器源码

      下载源码   技术要点: 1.本地音乐管理 2.在线音乐听歌.下载 3.音频流的解码 4. HTTP通信模块 5. Sqlite数据库 6. 源码带详细的中文注释 ...... 详细介绍: 1.本 ...

  10. DRF之解析器源码解析

    解析器 RESTful一种API的命名风格,主要因为前后端分离开发出现前后端分离: 用户访问静态文件的服务器,数据全部由ajax请求给到 解析器的作用就是服务端接收客户端传过来的数据,把数据解析成自己 ...

随机推荐

  1. vue 绑定样式,跟点击事件的顺序会影响

    <view class="mfst-item" v-for="(item, idx) in majorArr" :key="mfsKey&quo ...

  2. Vulnhub 靶场 CORROSION: 2

    Vulnhub 靶场 CORROSION: 2 前期准备 下载地址:https://www.vulnhub.com/entry/corrosion-2,745/ 靶机地址:192.168.147.19 ...

  3. anaconda在sys.path删除~/.local/lib

    python -m site python -m site -help USER_SITE='~/anaconda3/envs/test/lib/python3.7/site-packages'

  4. HTML5代码大全

    一.HTML各种命令的代码: 1.文本标签(命令)  <pre></pre>         创建预格式化文本 <h1></h1>         创建 ...

  5. git - git常用操作命令

    1.创建一个空的仓库 git init 2.配置git仓库 配置姓名 git config --global user.name '张三' 配置邮箱 git config --global user. ...

  6. NIO 缓冲区 ByteBuffer 之黏包和半包

    一.低效率方式 /** * 黏包.半包 */ private static void buffExample2() { /* 网络上传输多条数据给服务器,数据之间使用 \n 分隔. 但由于某种原因(多 ...

  7. sql 加工后--小文件解决方案

    10.24.8.5 # 切换用户 su - hive # 查看表文件 [hive@hadoop-0001 ~]$ hdfs dfs -ls /user/hive/warehouse/bibase.db ...

  8. mysql增删改查json中的某个字段

    创建表 1 CREATE TABLE t_json(id INT PRIMARY KEY, NAME VARCHAR(20), info JSON); 插入记录 1 INSERT INTO t_jso ...

  9. WAP-2.1

    WAP 是一种源代码静态分析和数据挖掘工具,用于检测和纠正用 PHP 4.0 或更高版本编写的 Web 应用程序中的输入验证漏洞,且误报率较低. WAP 检测并纠正以下漏洞: SQL Injectio ...

  10. Vue常用组件,,,持续更新中

    1.vue-lazyload :图片懒加载 2.vue-virtual-scroll-list 和 vue-virtual-scroller: 优化无限列表的场景 3.vue-table-with-t ...