{"id":13903010,"url":"https://github.com/zhangzhilinx/qsv2flv","last_synced_at":"2025-07-18T00:33:04.299Z","repository":{"id":62443217,"uuid":"243912419","full_name":"zhangzhilinx/qsv2flv","owner":"zhangzhilinx","description":"A tool developed in Rust to convert QSV to FLV（一个爱奇艺qsv转flv工具，不会生成多余的临时文件，使用Rust开发）","archived":false,"fork":false,"pushed_at":"2020-06-08T10:20:17.000Z","size":40,"stargazers_count":72,"open_issues_count":4,"forks_count":21,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-31T11:44:28.174Z","etag":null,"topics":["flv","qsv","qsv-flv","rust","std"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zhangzhilinx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-29T05:46:10.000Z","updated_at":"2024-10-21T08:00:18.000Z","dependencies_parsed_at":"2022-11-01T22:16:27.802Z","dependency_job_id":null,"html_url":"https://github.com/zhangzhilinx/qsv2flv","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangzhilinx%2Fqsv2flv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangzhilinx%2Fqsv2flv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangzhilinx%2Fqsv2flv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zhangzhilinx%2Fqsv2flv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zhangzhilinx","download_url":"https://codeload.github.com/zhangzhilinx/qsv2flv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226320859,"owners_count":17606367,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flv","qsv","qsv-flv","rust","std"],"created_at":"2024-08-06T22:01:33.534Z","updated_at":"2024-11-25T11:31:11.477Z","avatar_url":"https://github.com/zhangzhilinx.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# QSV转FLV (Rust移植版)\n\n![license](http://img.shields.io/badge/license-MPL%20v2-blue.svg)\n[![release](https://github.com/zhangzhilinx/qsv2flv/workflows/release/badge.svg)](https://github.com/zhangzhilinx/qsv2flv/releases)\n[![version](https://img.shields.io/crates/l/qsv2flv/0.1.2.svg)](https://crates.io/crates/qsv2flv)\n[![open issues](https://img.shields.io/github/issues-raw/zhangzhilinx/qsv2flv.svg)](https://github.com/zhangzhilinx/qsv2flv/issues)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-orange.svg)](https://github.com/zhangzhilinx/qsv2flv/pulls)\n\n\u003cbr\u003e\n\n## 简介\n\n一个可以将爱奇艺qsv格式视频转换为flv格式视频的简单命令行工具\n\n学习Rust后的第一个项目，感谢原C#项目作者提供的针对QSV的解决方案，也欢迎大家fork或者提交PR，帮助完善功能或者修复bug\n\n本程序仅支持QSV v2.0（可能无法处理某些较早的视频，比如说部分16年前的视频）\n\n前段时间用爱奇艺看电视时，想要收藏一些影视资源，于是去网上找相关的转码工具。遗憾的是，有些工具要么各种骗钱，要么不好用卡顿错帧。后面发现了一些不错的能够转换QSV的代码，但总觉得他们的实现有些仓促，于是用Rust重写，并做出了改进\n\nRust的开发的体验确实不错，解决了很多C++的痛点，同时又可以较大程度保证运行性能\n\n\u003cbr\u003e\n\n## 使用方法\n\n命令行运行 *（最近实现了交叉编译，提供了多种系统平台下已编译好的程序）*\n\n```out\nqsv2flv 0.1.1\nZhangZhilin \u003ccorex_public@outlook.com\u003e\nA tool for converting QSV to FLV\n\nUSAGE:\n    qsv2flv [FLAGS] \u003cINPUT\u003e \u003cOUTPUT\u003e\n\nFLAGS:\n    -h, --help       Prints help information\n    -V, --version    Prints version information\n    -v, --verbose    Print test information verbosely\n\nARGS:\n    \u003cINPUT\u003e     Sets the input file to use\n    \u003cOUTPUT\u003e    Sets the output file to use\n```\n\n\u003cbr\u003e\n\n## 功能特性\n\n* 仅供学习用途（切勿将该项目用于非法盈利）\n\n* 提供了简单的命令行前端交互\n\n* 转换速度快\n  \n  * 在SSD硬盘下：效率大约是C#版本的2倍，与另一个由C++复刻的实现接近\n  * 在HDD硬盘下：有时能快于C++复刻实现的2倍\n  * 该结果是在Windows平台（后端为msvc）下试验得到的，也许LLVM后端可能会有更好的性能表现\n\n* 不会生成临时文件\n  \n  * 减少固态不必要的写寿命损耗\n  * 在读写相对较慢的HDD上，快于C++复刻的版本，部分情况下转码速度可达2倍\n  * 实现思路的性能瓶颈主要是相对更频繁的随机seek操作\n\n\u003cbr\u003e\n\n## 设计细节\n\n执行顺序：\n\n```rust\n// 将QSV转换为FLV\nfn convert_qsv_to_flv(qsv: \u0026mut File, flv: \u0026mut File) -\u003e Result\u003c()\u003e\n    /* [步骤] 检查QSV文件是否正确 */\n    // 验证QSV格式\n    fn validate_qsv_format(qsv: \u0026mut File) -\u003e Result\u003c()\u003e\n\n    /* [步骤] 解析QSV文件中 */\n    // 从QSV中解析得到每个TAG块的信息\n    fn tag_blocks_from_qsv(qsv: \u0026mut File) -\u003e io::Result\u003cFlvTagBlocks\u003e\n        // 将QSV文件seek至QSV的TAGS的起始处\n        fn seek_qsv_to_start(qsv: \u0026mut File) -\u003e io::Result\u003c()\u003e\n        // 使QSV文件的seek指针跳过元数据开头\n        fn skip_qsv_metadata(qsv: \u0026mut File) -\u003e io::Result\u003c()\u003e\n    // 从所有TAG块获取FLV的元数据\n    fn meta_data_from_tag_blocks(qsv: \u0026mut File, tags: \u0026[FlvTagBlock]) -\u003e Result\u003cMetaData\u003e\n        // 解析视频TAG块信息 (是否为关键帧, 视频编码ID)\n        fn parse_video_tag(qsv: \u0026mut File, tag: FlvTagBlock) -\u003e Result\u003c(bool, u8)\u003e\n        // 解析音频TAG块信息 (音频编码ID, 音频采样率, 音频采样大小, 音频是否为立体声)\n        fn parse_audio_tag(qsv: \u0026mut File, tag: FlvTagBlock) -\u003e Result\u003c(u8, u8, u8, bool)\u003e\n        // 从TAG块中读取时间戳\n        fn get_time_stamp_from_tag(qsv: \u0026mut File, tag: \u0026FlvTagBlock) -\u003e Result\u003ci32\u003e\n\n    /* [步骤] 正在写入到FLV文件中 */\n    // 根据已提取出的TAG块信息和FLV元数据，将QSV转换为FLV\n    fn write_from_qsv_to_flv(qsv: \u0026mut File, tags: \u0026[FlvTagBlock], flv: \u0026mut File, meta: \u0026MetaData)\n        -\u003e Result\u003c()\u003e\n```\n\n错误类型：\n\n```rust\npub enum ErrorKind {\n    Io(std::io::Error),      // 文件系统IO错误\n    IncorrectQsvVersion,     // 错误的QSV版本：本程序无法处理\n    IncorrectQsvFormat,      // 错误的QSV格式：不符合预期格式/该文件不是QSV\n    QsvTagsIsEmpty,          // 该QSV文件TAG块数量小于1个\n    MediaDurationIsTooShort, // 媒体时长过短\n}\n```\n\n\u003cbr\u003e\n\n## 计划事项\n\n### 计划任务\n\n\u003e * 检查输出路径是否已存在文件，询问覆盖，防止因File::create(...)导致意外覆盖\n\u003e \n\u003e * 性能探查：valgrind, qcachegrind\n\u003e \n\u003e * ```rust\n\u003e   trait FilePlus {\n\u003e       fn read_byte(\u0026mut self) -\u003e std::io::Result\u003cOption\u003cu8\u003e\u003e;\n\u003e       fn write_byte(\u0026mut self, u8) -\u003e io::Result\u003cbool\u003e;\n\u003e       fn tell(\u0026mut self) -\u003e std::io::Result\u003cu64\u003e;\n\u003e   }\n\u003e   impl FilePlus for File {\n\u003e       //...\n\u003e   }\n\u003e   ```\n\u003e \n\u003e * 性能优化：unsafe优化\n\u003e \n\u003e * 详细进度显示\n\u003e \n\u003e * 确保宿主机跨平台可移植性：跨系统、大小端、32位/64位\n\u003e \n\u003e * 完善注释、文档\n\n### 计划特性\n\n\u003e * 支持管道输出/重定向输出\n\u003e * 改进FLV生成，提供更多可设定的FLV元数据参数（建议引入：flavors \u0026\u0026 nom）\n\u003e * 支持批量文件转码\n\n\u003cbr\u003e\n\n## 性能测试\n\n简单测试样例：\n\n\u003e | 文件名称                       | 文件大小  | 存储介质             | 本项目[Rust]用时 | 其他版[C++]用时 |\n\u003e | -------------------------- | ----- | ---------------- | ----------- | ---------- |\n\u003e | iPartment 5第2集-蓝光1080P.qsv | 842MB | 2.5英寸希捷**机械**    | 34.095s     | 65.914s    |\n\u003e | iPartment 5第1集-蓝光1080P.qsv | 895MB | 2.5英寸Intel**固态** | 14.048s     | 13.537s    |\n\u003e | Smooth Criminal.qsv        | 18MB  | 2.5英寸Intel**固态** | 0.442s      | 0.143s     |\n\n\u003cbr\u003e\n\n## 更新记录\n\n* v0.1.0\n  \n  * 更新日志\n    \n    - 第一个可用版本\n    - 避免了临时文件的生成\n  \n  * 备注\n    \n    - 这是命令行程序，没有提供图形界面，但是使用方法并不难\n\n* v0.1.1\n  \n  * 更新日志\n    \n    - 增加了磁盘缓存同步步骤，防止在某些意外情况下可移动磁盘数据丢失\n    - 改动了错误处理代码，因为相关代码被新Rust版本标记为deprecated\n\n* v0.1.2\n  \n  * 更新日志\n    \n    * 重构了少量代码，改善了代码风格，也因此改动了部分函数签名\n  \n  * 备注\n    \n    - 该版本代码行为上与v0.1.1一致，主要集中在代码风格、文档的改进\n    - 将宏代码分离到单独模块: `macros.rs`\n    - 提供了多种平台的编译结果\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhangzhilinx%2Fqsv2flv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzhangzhilinx%2Fqsv2flv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzhangzhilinx%2Fqsv2flv/lists"}