赞
踩
这篇文章使用了笨方法,后来在网上看到了
you-get
这款工具,可以在命令行通过URL直接下载视频,而且支持批量下载。
B站只允许使用手机缓存视频,但是缓存下来的视频分散在不同的文件夹里,而且每个视频的名称都是 0.blv
,不点开看的话根本不知道是哪个视频,所以写了一个辅助提取B站Android客户端缓存视频的小工具。
因为恰好开着Unity,所以就直接在Unity里面写了下面的这段代码,因而用了一些Unity的专用类,如果要在其他地方使用下面的代码,需要把文中提到的几个特殊类替换掉。
使用方法
这个工具是用来处理视频量比较大的视频合集的,如果是单个视频,直接手动复制视频然后重命名就好了。
用法很简单,在手机上把视频缓存好以后,手机连接电脑,打开视频的缓存文件夹,把缓存合集拖到复制到电脑上,然后再Unity的 Inspector 面板上填写视频位置信息,点击 Extract
即可完成提取。如果不想在Unity中使用,那么需要把下面提到的几个特殊类替换掉,然后调用 ExtractVideoFile()
方法提取视频。
注意:代码里处理视频用的是剪切方法,如果不把缓存的视频从手机里复制出来就直接运行代码,会把缓存的视频剪切到其他位置。如果不想剪切,可以把代码中的
File.Move()
方法改成File.Copy()
方法。
参数示例
备注:有些视频集里面的单集视频会被分成多个视频文件(例如:0.blv,1.blv,2.blv等),这里没写处理方法。如果遇到这种情况,可以进行多次提取,每次提取时修改一下
源文件名称参数VideoName
和输出文件扩展名参数OutputExt
(例如:VideoName:"1.blv"
,OutputExt:"-1.flv"
)。多次提取时,已经提取过的文件会报找不到视频文件
的错误,可以忽略。
B站Android客户端的一些相关信息
手机内部存储\Android\data\tv.danmaku.bili\download\
;手机内部存储\Android\data\tv.danmaku.bili\download\<avid>\<index>\<lua.xxx.xxx.xxx>\<x.blv>
;手机内部存储\Android\data\tv.danmaku.bili\download\<avid>\<index>\entry.json
;avid
、 index
、 lua.xxx.xxx.xxx
、 x.blv
需要根据下载的文件的具体名称进行修改,代码中的 domain
参数就是 lua.xxx.xxx.xxx
部分。用到的特殊类及其方法
源代码
using System.IO; using UnityEngine; public class BilibiliTool : MonoBehaviour { /** 说明 * B站Android客户端缓存视频的存放文件夹是“手机内部存储\Android\data\tv.danmaku.bili\download\”; * 具体的视频路径是“手机内部存储\Android\data\tv.danmaku.bili\download\<avid>\<index>\<lua.xxx.xxx.xxx>\<x.blv>”; * 存储每个视频的信息的文件是“手机内部存储\Android\data\tv.danmaku.bili\download\<avid>\<index>\entry.json”; * 上述说明中的<avid>、<index>、<lua.xxx.xxx.xxx>、<x.blv>需要根据下载的文件的具体名称进行修改,代码中的“domain”参数就是“lua.xxx.xxx.xxx”部分。 */ // 默认值仅作示例,每个视频集的avid和视频父文件夹名称都不一样,要进行相应的修改 public string inputFolder = @"E:\资料\视频教程\46312220\"; public string outputFolder = @"E:\资料\视频教程\线性代数\"; public string domain = "lua.flv720.bili2api.64"; public int startNumber = 1; public int endNumber = 116; public string videoName = "0.blv"; public string outputExt = ".flv"; public string jsonName = "entry.json"; [Header("点击勾选框执行提取")] public bool extract = false; private void OnValidate() { if (extract) { extract = false; ExtractVideoFile(inputFolder, outputFolder, domain, startNumber, endNumber, videoName, outputExt, jsonName); } } /// <summary> /// 提取视频文件。 /// </summary> /// <param name="inputFolder">存放下载的原始视频的文件夹</param> /// <param name="outputFolder">提取视频的输出文件夹</param> /// <param name="domain">原始视频文件路径中格式为“lua.x.x.x”的文件夹的名称</param> /// <param name="startNumber">视频合集中视频的起始编号</param> /// <param name="endNumber">视频合集中视频的结束编号</param> /// <param name="videoName">原始视频名称(默认为0.blv)</param> /// <param name="outputExt">输出视频文件的扩展名(默认为flv)</param> /// <param name="jsonName">存储视频信息的Json文件的名称(默认为entry.json)</param> public void ExtractVideoFile(string inputFolder, string outputFolder, string domain, int startNumber, int endNumber, string videoName = "0.blv", string outputExt = ".flv", string jsonName = "entry.json") { // 检查输入路径 if (!Directory.Exists(inputFolder)) { Debug.LogError("文件路径<" + inputFolder + ">不存在。", this); return; } // 检查输出路径 if (!Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } // 移动和重命名 for (int i = startNumber; i < endNumber + 1; i++) { // 将原始视频移动到指定位置 string sourceFilePath = string.Format(@"{0}\{1}\{2}\{3}", inputFolder, i, domain, videoName); if (!File.Exists(sourceFilePath)) { Debug.LogError("找不到视频文件<" + sourceFilePath + ">。", this); continue; } // 可能读不到文件或者格式无法正常解析 string jsonPath = string.Format(@"{0}\{1}\{2}", inputFolder, i, jsonName); try { string json = File.ReadAllText(jsonPath); Bilibili bili = JsonUtility.FromJson<Bilibili>(json); // 重命名视频 string name = bili.page_data.part; string outputFilePath = string.Format(@"{0}\{1}{2}", outputFolder, name, outputExt); File.Move(sourceFilePath, outputFilePath); } catch { Debug.LogError("无法解析文件<" + jsonPath + ">。", this); continue; } } Debug.Log("视频提取完成。", this); } } /// <summary> /// 手机内部存储\Android\data\tv.danmaku.bili\download\avid\index\entry.json的格式。 /// </summary> [System.Serializable] public class Bilibili { public bool is_completed; public int total_bytes; public int downloaded_bytes; public string title; public string type_tag; public string cover; public int prefered_video_quality; public int guessed_total_bytes; public int total_time_milli; public int danmaku_count; public int time_update_stamp; public int time_create_stamp; public int avid; public int spid; public int seasion_id; public PageData page_data; [System.Serializable] public class PageData { public int cid; public int page; public string from; public string part; public string vid; public bool has_alias; public string weblink; public int tid; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。