C#:将blibli缓存文件批量转换为MP4文件

一、概述:我们主要处理哔哩哔哩缓存文件夹每一集中的audio.m4s和video.m4s以及entry.json文件,audio.m4s内容是每一集的音频文件,而vedio.m4s内容是视频的画面,也就是说哔哩哔哩将一个视频分解为音频部分和视频画面两部分,而我们要做的将这两部分合成并转换为MP4格式的文件,那么这个MP4文件到底取什么名字呢?这是就需要entry.json文件了,这里面存放的是视频每一集的基本信息,通过这个文件里面的信息来给出输出文件命名。

二、实现步骤:

1.递归访问指定文件目录找出每一集的audio.4ms文件、video.4ms文件以及entry.json文件

2.获取entry.json中的视频信息(视频集数名字)

3.调用进程ffmpeg(程序)将audio.4ms文件、video.4ms文件合成MP4文件

具体步骤:

1.递归找出所有需要文件的路径:

var cap=new List<string>(){};//定义的保存所有文件路径的容器

var cap1=new List<string>(){};

cap=GetAllFilesFromPath(inpath,true);//保存所有的audio.4ms文件和video.4ms文件路径

cap1=GetAllFilesFromPath(inpath,"*entry.json",true);//保存所有entry.json文件路径

具体代码如下:

public static bool ExistsDirectory(string direName){return System.IO.Directory.Exists(direName);}// 递归获取某一目录下的符合条件的所有文件 public static List<string> _GetAllFilesFromPath(string path, string filter, bool DiGui = true)//这里DiGui为true代表使用递归调用{List<string> files = new List<string>();if (!ExistsDirectory(path))//如果该文件目录存在return files;if (DiGui){string[] dirs = Directory.GetDirectories(path);//得到子目录foreach (var str in dirs)files.AddRange(GetAllFilesFromPath(str, filter, DiGui));}string[] tempfiles = Directory.GetFiles(path, filter);files.AddRange(tempfiles);return files;}public static List<string> GetAllFilesFromPath(string path, string filters, bool DiGui = true){List<string> files = new List<string>();if (!string.IsNullOrWhiteSpace(filters)){foreach (var item in filters.Split(new Char[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries)){var _files = _GetAllFilesFromPath(path, item, DiGui);foreach (var _file in _files){files.Add(_file);}}return files;}elsereturn GetAllFilesFromPath(path, DiGui);}// 递归获取某一目录下的mp4所有文件public static List<string> GetAllFilesFromPath(string path, bool DiGui = true){return GetAllFilesFromPath(path, "*.m4s", DiGui);}

2.通过访问每一集的entry.json文件,获得输出文件名

a.OutFile=outpath+@"\"+GetFileJson(cap1[i]);//这里的a.outFile就是输出路径和文件名, GetFileJson(cap1[i])就是获取每个entry文件中的part部分后面的字符串名,至于我为啥要写字符串处理函数GetFileJson(cap1[i])呢?那是因为我的SharpDevelop 5.1软件无法引入处理.json的文件,所以就自己写了一个。

至于.json文件里面到底有些啥呢?我们打开一个来看看

{"media_type":2,"has_dash_audio":true,"is_completed":true,"total_bytes":6436658,"downloaded_bytes":6436658,"title":"ITZY新曲Mafia In the morning舞蹈版MV公开","type_tag":"16","cover":"http:\/\/i0.hdslb.com\/bfs\/archive\/8a5f741fd079af38481b177877ec4f0350d80651.jpg","video_quality":16,"prefered_video_quality":16,"guessed_total_bytes":0,"total_time_milli":182101,"danmaku_count":85,"time_update_stamp":1620308481186,"time_create_stamp":1620308477092,"can_play_in_advance":true,"interrupt_transform_temp_file":false,"quality_pithy_description":"360P","quality_superscript":"","cache_version_code":6235200,"preferred_audio_quality":0,"audio_quality":0,"avid":417942654,"spid":0,"seasion_id":0,"bvid":"BV1SV41177mc","owner_id":16720403,"page_data":{"cid":334369010,"page":1,"from":"vupload","part":"MV","link":"","vid":"","has_alias":false,"tid":193,"width":3840,"height":2160,"rotate":0,"download_title":"视频已缓存完成","download_subtitle":"ITZY新曲Mafia In the morning舞蹈版MV公开 MV"}}

而我主要将part后面部分截取了下来也就是MV,即将MV作为文件的一个输出名。

代码如下:

//获取文件名字public static string GetFileJson(string filepath){string json = string.Empty;string c="";using (FileStream fs = new FileStream(filepath, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite)){using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("UTF-8"))){json = sr.ReadLine().ToString();int j=0;for(int i=0;i<json.Length;i++){                   if(json[i]=='"')if(json[i+1]=='p')if(json[i+2]=='a')if(json[i+3]=='r')  if(json[i+4]=='t'){j=i;j=j+8;break;}    }while(json[j]!='"'){   c=c+json[j];j++;}c=c+".mp4";}}return c;}

3.调用ffmpeg文件合成.mp4文件

a.ConvertVideo();//调用ffmpeg文件

代码如下:

 public class CFfmpeg{public static string ffmpegtool = @"D:\ffmpeg\bin\ffmpeg.exe";//ffmpeg.exe文件下载路径public static string outFile = @"D:\ffmpeg\bin\972637678\c_328764377\16\output2.mp4";//默认输出路径public static string sourceFile = @"D:\ffmpeg\input\417942654\c_334370165\16\audio.m4s";//默认音频路径public static string sourceFile1 = @"D:\ffmpeg\input\417942654\c_334370165\16\video.m4s";//默认视频画面路径public string SourceFile{set{sourceFile=value;}get{return sourceFile;}}public string SourceFile1{set{sourceFile1=value;}get{return sourceFile1;}}public string OutFile{set{outFile=value;}get{return outFile;}}public void ConvertVideo(){Process p = new Process();//建立外部调用线程p.StartInfo.FileName = ffmpegtool;//要调用外部程序的绝对路径//传入FFMPEG的参数                          string strArg = " -i " + sourceFile +" -i "+sourceFile1 + " -codec copy "+outFile ;p.StartInfo.Arguments = strArg;p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中p.StartInfo.CreateNoWindow = false;//不创建进程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//这里是FFMPEG输出流的时候产生的事件,这里是把流的处理过程转移到下面的方法中p.Start();//启动线程p.BeginErrorReadLine();//开始异步读取p.WaitForExit();//阻塞等待进程结束p.Close();//关闭进程p.Dispose();//释放资源}private void Output(object sendProcess, DataReceivedEventArgs output){if (!String.IsNullOrEmpty(output.Data)){Console.WriteLine(output.Data);  }}}

三、完整代码

/** Created by SharpDevelop.* User: 12875* Date: 2021/4/23* Time: 14:24* * To change this template use Tools | Options | Coding | Edit Standard Headers.*/
/*1.如何调用外部命令。(解决)* 2.如何解析集数(entry.json)文件中。* 3.连续的递归查找要转换的每一集。* * * */
using System;
using System.Linq;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Collections.Generic;
//\ffmpeg.exe -i video.m4s -i audio.m4s -codec copy Output.mp4
namespace c20210423
{class Program{//获取文件名字public static string GetFileJson(string filepath){string json = string.Empty;string c="";using (FileStream fs = new FileStream(filepath, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite)){using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("UTF-8"))){json = sr.ReadLine().ToString();int j=0;for(int i=0;i<json.Length;i++){                   if(json[i]=='"')if(json[i+1]=='p')if(json[i+2]=='a')if(json[i+3]=='r')  if(json[i+4]=='t'){j=i;j=j+8;break;}    }while(json[j]!='"'){   c=c+json[j];j++;}c=c+".mp4";}}return c;}public static bool ExistsDirectory(string direName){return System.IO.Directory.Exists(direName);}// 递归获取某一目录下的符合条件的所有文件 public static List<string> _GetAllFilesFromPath(string path, string filter, bool DiGui = true)//这里DiGui为true代表使用递归调用{List<string> files = new List<string>();if (!ExistsDirectory(path))//如果该文件目录存在return files;if (DiGui){string[] dirs = Directory.GetDirectories(path);//得到子目录foreach (var str in dirs)files.AddRange(GetAllFilesFromPath(str, filter, DiGui));}string[] tempfiles = Directory.GetFiles(path, filter);files.AddRange(tempfiles);return files;}public static List<string> GetAllFilesFromPath(string path, string filters, bool DiGui = true){List<string> files = new List<string>();if (!string.IsNullOrWhiteSpace(filters)){foreach (var item in filters.Split(new Char[] { ',', '|' }, StringSplitOptions.RemoveEmptyEntries)){var _files = _GetAllFilesFromPath(path, item, DiGui);foreach (var _file in _files){files.Add(_file);}}return files;}elsereturn GetAllFilesFromPath(path, DiGui);}// 递归获取某一目录下的mp4所有文件public static List<string> GetAllFilesFromPath(string path, bool DiGui = true){return GetAllFilesFromPath(path, "*.m4s", DiGui);}//合成音频文件public class CFfmpeg{public static string ffmpegtool = @"D:\ffmpeg\bin\ffmpeg.exe";//ffmpeg.exe文件下载路径public static string outFile = @"D:\ffmpeg\bin\972637678\c_328764377\16\output2.mp4";//默认输出路径public static string sourceFile = @"D:\ffmpeg\input\417942654\c_334370165\16\audio.m4s";//默认音频路径public static string sourceFile1 = @"D:\ffmpeg\input\417942654\c_334370165\16\video.m4s";//默认视频画面路径public string SourceFile{set{sourceFile=value;}get{return sourceFile;}}public string SourceFile1{set{sourceFile1=value;}get{return sourceFile1;}}public string OutFile{set{outFile=value;}get{return outFile;}}public void ConvertVideo(){Process p = new Process();//建立外部调用线程p.StartInfo.FileName = ffmpegtool;//要调用外部程序的绝对路径//传入FFMPEG的参数                          string strArg = " -i " + sourceFile +" -i "+sourceFile1 + " -codec copy "+outFile ;p.StartInfo.Arguments = strArg;p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中p.StartInfo.CreateNoWindow = false;//不创建进程窗口p.ErrorDataReceived += new DataReceivedEventHandler(Output);//这里是FFMPEG输出流的时候产生的事件,这里是把流的处理过程转移到下面的方法中p.Start();//启动线程p.BeginErrorReadLine();//开始异步读取p.WaitForExit();//阻塞等待进程结束p.Close();//关闭进程p.Dispose();//释放资源}private void Output(object sendProcess, DataReceivedEventArgs output){if (!String.IsNullOrEmpty(output.Data)){Console.WriteLine(output.Data);  }}}public static void Main(string[] args){Console.WriteLine("Hello World!");string inpath=@"D:\ffmpeg\input";//要递归访问的文件目录默认路径string outpath=@"D:\ffmpeg\output";//生成文件输出目录默认路径var cap=new List<string>(){};var cap1=new List<string>(){};if(args.Length==0){inpath=@"D:\ffmpeg\input";outpath=@"D:\ffmpeg\output";}else if(args.Length==2){inpath=args[0];outpath=args[1];}  cap=GetAllFilesFromPath(inpath,true);//保存路径cap1=GetAllFilesFromPath(inpath,"*entry.json",true);//保存的是文件名CFfmpeg a=new CFfmpeg();for(int j=0;j<cap1.Count;j++){Console.WriteLine(GetFileJson(cap1[j]));}for(int i=0;i<cap1.Count;i++){a.SourceFile1=cap[2*i];a.SourceFile=cap[2*i+1];Console.WriteLine(cap[2*i]);Console.WriteLine(cap[2*i+1]);a.OutFile=outpath+@"\"+GetFileJson(cap1[i]);a.ConvertVideo();}Console.Write("Press any key to continue . . . ");Console.ReadKey(true);}}
}

四、效果显示

C#:将blibli缓存文件批量转换为MP4文件相关推荐

  1. Bilibili手机端下载的Download文件批量转换为MP4软件【Bilibili_DownVideoToMp4】原创发布

    Bilibili手机端下载的Download文件批量转换为MP4软件[Bilibili_DownVideoToMp4]原创发布 起因 Bilibili手机端的视频下载下来只能在手机上看,手机屏幕太小看 ...

  2. 将DWG文件批量转换为JPG文件

    我们在工作上需要将DWG文件转换为JPG文件,在公司里有很多的DWG文件图纸转换JPG文件,我们不可能一个一个的转换,这时候我们为了提高工作效率需要将DWG文件批量转换为JPG文件,DWG文件批量转换 ...

  3. RTF 批量转换为 DOCX 文件

    RTF 批量转换为 DOCX 文件   RTF是多信息文本格式,可用于多设备.系统.最近在做一个小的数据批量处理程序时遇到了RTF格式的数据文件,这种格式虽然跨设备跨系统,但是发现解析此格式的库比较少 ...

  4. 记录----如何将FLV格式文件快速转换为mp4文件

    如何将FLV格式文件快速转换为mp4文件 今天用硕鼠下载视频的时候发现下载出来的视频是.flv格式的,没有相应的播放器无法播放,于是找了个方法把它转换为MP4文件,记录一下 第一步 下载一个辅助工具, ...

  5. 如何在Excel中将多个Excel文件批量转换为CSV文件?

    在Excel中,我们可以使用"另存为"功能将工作簿转换为CSV文件,但是您知道如何将多个Excel文件批量转换为单独的CSV文件吗? 在本文中,我介绍了一个VBA代码,用于将文件夹 ...

  6. mp4转换m3u8格式php,【过程】第一次将m3u8文件转换为MP4文件经验分享

    因为工作原因,要将之前{中国影视童星大赛}的网络上的回放保存到本地下来,是微信里面的网页,用电脑打开的话,不会有下载按钮,手机用UC浏览器看视频一般都会有下载按钮,索性我就用uc下载到手机上再传到电脑 ...

  7. 后缀为php的怎样转换成m3u8,【过程】第一次将m3u8文件转换为MP4文件经验分享

    因为工作原因,要将之前{中国影视童星大赛}的网络上的回放保存到本地下来,是微信里面的网页,用电脑打开的话,不会有下载按钮, 手机用UC浏览器看视频一般都会有下载按钮, 索性我就用uc下载到手机上再传到 ...

  8. python + ffmpeg 将某站的缓存视频文件批量转换为MP4格式

    这是一篇很无聊的文章,之所以写它是因为这周还没写博客,但是好像没啥可写的,刚好今天突发奇想,想要把某站的APP缓存视频文件转化为mp4 格式,方便在电脑上看,方法很简答,很快就做完了,所以,又一篇水文 ...

  9. php 把ppt转pdf文件大小,ppt转换成pdf 怎么将ppt文件批量转换为pdf文件?ppt高质量转换pdf的方法...

    在工作上,有时候要处理多个文件,并且会涉及到各种资料文档的格式转换问题.前两天就有狸友跟小编说工作中需要将大量资料文件ppt转换成pdf格式再传输给他人.如果一个个将ppt转化为pdf的话工作量也是很 ...

最新文章

  1. Wireless-N Configuration
  2. 记一次validator jar冲突导致的启动异常
  3. 01-JDBC学习手册:JDBC概述之JDBC发展、API、驱动
  4. Go版本升级后编译出错:Load redeclared in this block
  5. Delphi下载指定网址(URL)的文件,带进度条显示
  6. c语言用hash方式数组去重,js数组去重的hash方法
  7. 关于.Net2.0下配置架构的使用
  8. luogu4267 TamingtheHerd (dp)
  9. bzoj1143/2718 祭祀river(最大独立集)
  10. Struts2.x中获取request,response,session的方式
  11. 数据统计作业0429_因子分析/FA
  12. 金融评分卡项目—6.互联网金融业贷款申请评分卡介绍
  13. java一个进程可以村多少个线程_一台 Java 服务器可以跑多少个线程?
  14. 海思isp图像处理芯片_最新海思芯片3559A的功能简介
  15. mysql优化-Explain工具介绍
  16. API调用,淘宝天猫、1688、京东、拼多多商品页面APP端原数据获取
  17. 推荐的Qt论坛+个人博客+网站
  18. 618 大促运营必看!4 步教你玩转商品运营
  19. 作者:王印海(1965-),男,美国华盛顿大学(西雅图)土木和环境工程系终身教授、博士生导师。...
  20. 摩拜获巨额融资,为何还被曝拖欠底层员工薪水?

热门文章

  1. 松下FP7大型plc程序,一共三十多个电机,轴控制程序模块化
  2. 自学鸿蒙应用开发(25)- 基本的CommonDialog
  3. STM32从零开始(三) 点亮led灯并且配置时钟为72mhz
  4. SpringBoot+Netty构建高并发稳健的部标JT808网关
  5. Modelsim仿真错误
  6. pandas中的read_csv参数详解
  7. 一文读懂功率信号源(信号发生器)
  8. 365. 水壶问题-暴力模拟倒水过程-递归法
  9. ajax 调用sqlserver,js连接sqlserver进行查询
  10. win10使用WinAppDriver实现UI自动化