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. 【FPGA & Verilog】手把手教你实现一个DDS信号发生器

    信号发⽣器的设计与实现 1.输出波形:⽅波(占空⽐50%).锯⻮波.三⻆波.脉冲信号(占空⽐连续可调).正弦波.任意波等 2.输出频率:100KHz 3.波形选择:使⽤拨码开关选择   思路: 使用F ...

  2. Demo of canvas, canvas optimization and svg

    It used the canvas to draw the curves in the old project, and the client felt that it was vague, so ...

  3. highcharts冷门功能总结

    1.散点图控制点的样式. Highcharts.chart('container', { series: [{ type: "scatter", marker: { fillCol ...

  4. 页面布局 Stack 层叠组件 Stack 与 Align Stack 与 Positioned 实现定位布局

    一.Flutter Stack 组件 Stack 表示堆的意思,我们可以用 Stack 或者 Stack 结合 Align 或者 Stack 结合 Positiond 来实现页面的定位布局 属性 说明 ...

  5. APP数据指标体系分析

    一.APP的数据指标体系主要分为五个维度,包括用户规模与质量.参与度分析.渠道分析.功能分析和用户属性分析. 1.用户规模和质量 用户规模和质量是APP分析最重要的维度,其指标也是相对其他维度最多,数 ...

  6. 摩托罗拉IP PBX9000配置指南

    400通话时,按数字键进行选择无效 打开IPB通信板界面,SIP终端参数--应用设置--点击RFC2833数值,默认禁用变更为101,(如有多个勾选批量,填写批量数值)--提交--保存修改 未完待续

  7. Typora笔记收费的解决

    现在的Typora收费了,但是官网还是可以找到历史版本 Typora在1.0版本之前的不收费!!! 所有只需要下载1.0版本之前的版本就可以解决 Windows历史版本地址:https://typor ...

  8. svn提交注释限制

    找到svn仓库 目录结构长这样 在hooks下的新建一个名字为pre-commit.bat的可执行文件 注意:findstr后边的.通配符表示一个任意字符,findstr "." ...

  9. mysql建表常用关键字

    DISTRIBUTE BY HASH(`id`) INDEX_ALL='Y' STORAGE_POLICY='HOT'

  10. MySQL索引 及 EXPLAIN

    1.索引长度计算: 1.索引字段,没有设置NOT NULL,则需要加一个字节. 2.定长字段:tinyiny占1个字节.int占4个字节.bitint占8个字节.date占3个字节.datetime占 ...