本人喜歡在B站上看視頻,無奈B站的資源有時候會突然就沒了,就會把那些好的資源下載到手機上,主要是PC端的B站貌似不直接支持下載,然後再傳到電腦上。在PC端打開相關資源一看,全是數字命名,有用的資料全在JSON文件裏。一個倆個還可以手動命名,這一下有幾十個,就有點考驗人了。遂想利用所學的Qt將其自動命名並移動到特定的文件夾裏,而且那個視頻的格式是blv的,一般播放器壓根打不開,幸好我用的是PotPlayer,可以打開但是播放列表只能顯示打開的那個,沒打開的就不會顯示在播放列表裏,還得重新去打開文件播放。我嘗試直接更改後綴名爲mp4,文件可以播放沒播放的文件也能顯示在播放列表上,完美。下圖是原始的視頻資料,其中0.blv就是視頻資源,可以用PotPlayer播放,entry.json記載了相關資料,待會命名就得從這裏面找相關的名字。
這個是entry.json裏的視頻名稱,待會在程序解析json的時候會用到
1.新建工程,然後再widget.h裏添加相關頭文件
#include <QJsonDocument> //這個是對JSON文檔的支持
#include <QJsonParseError> //解析JSON時出錯就靠它來判斷
#include <QJsonObject> //對JSON對象的支持
#include <QFile> //文件操作
#include <QDir> //目錄操作
#include <QDebug> //方便調試
2.創建相關變量並初始化
private:
Ui::Widget *ui;
QString path; //文件所在路徑
QString dPath; //將提取出來的視頻重新放置的文件夾路徑
QString nameDir; //視頻所在的上層文件夾名,就是entry.json中的type_tag的值
QString NameEntry; //解析出來的視頻名字,就是entry.json中的title中的值
QStringList list; //文件列表
QStringList dirList; //目錄列表
path = "F:/B站視頻/試試"; //文件所在的路徑
dPath = "F:/B站視頻/試試/"; //將視頻重新存放的路徑
readDir(); //開始解析相應的文件夾
3.readDir()函數的實現,並且這個是按固定格式來的,例如在以我電腦上的路徑舉例,現在當前目錄(試試)一個一個遍歷,在每一個文件夾(1)中又再次遍歷尋找entry.json文件並進行解析,如果解析成功,則再次進行視頻所在的文件夾(lua.flv360.bili2api.16)再次遍歷查找視頻文件,對其進行重命名(包括更換路徑)。由於沒重構過,所有整體看起來有點亂,命名也是,還請見諒。
void Widget::readDir()
{
QDir dir(path);
if(!dir.exists()){ //判斷相應的目錄是否存在
qDebug() << "dir isn't exist ";
return;
}
QFileInfoList li = dir.entryInfoList();//將當前文件夾下的所有目錄存在li鏈表中,方便查找
if(li.size() > 0){ //判斷
int i=0;
bool flag = false; //判斷是否已經找到
//這裏加2是因爲每個目錄都隱藏有倆個索引上面目錄..和索引本層目錄.,加2可避免掉
for(QFileInfoList::Iterator it = li.begin() + 2;
it != li.end();it ++,i++){//遍歷循環
QDir basedir(it->absoluteFilePath()); //得到遍歷到得目錄的信息
QFileInfoList baselist = basedir.entryInfoList();//同上
for(QFileInfoList::Iterator add = baselist.begin() + 2;
add != baselist.end();add ++){//再次遍歷本層目錄
if(add->baseName() == "entry"){//找到entry.json文件
flag = AnalyJson(add->absoluteFilePath());//進行文件解析
break;
}
}
if(flag){//解析成功,得到相應的結果
//得到完整的視頻路徑
QString file0 = it->absoluteFilePath() + "\\" + nameDir;
QDir dir80(file0);// nameDir得到當前文件夾信息
if(!dir80.exists()){ //判斷是否存在
qDebug()<<"no exist"<<it->absoluteFilePath();
continue;
}
QFileInfoList fileinfolist = dir80.entryInfoList();//同上
for(QFileInfoList::Iterator it1 = fileinfolist.begin() + 2;
it1 != fileinfolist.end();it1 ++){//進行遍歷,查找0.blv文件
if(it1->fileName() == "0.blv"){//尋找0.blv文件
//新文件名,在此更換路徑
QString newPath = dPath+NameEntry+".mp4";
QString oldPath = it1->absoluteFilePath();
if(QFile::rename(oldPath,newPath)){//進行重命名
qDebug() << "successful";
break;
}
}
}
}
}
}
else{
qDebug() << " li is 0";
}
}
4.AnalyJson(QString pa)的實現,並獲取相關信息,如果獲取成功則返回true。
bool Widget::AnalyJson(QString pa)
{
QFile fileLoad(pa);//加載該該JSON文件
if(!fileLoad.open(QIODevice::ReadOnly)){//判斷是否打開成功
qDebug() << "json is no ";
return false;
}
QByteArray data = fileLoad.readAll();//得到當前文件所有內容
fileLoad.close();//關閉文件
QJsonParseError jsonError;//用來判斷是否解析JSON過程是否出錯
QJsonDocument jsonDoc(QJsonDocument::fromJson(data,&jsonError));//解析
if(jsonError.error != QJsonParseError::NoError){
qDebug() << "Json open error";
return false;
}
//將解析出來的文檔轉化爲對象格式
QJsonObject obj = jsonDoc.object();
NameEntry = obj.value("title").toString();//得到文件名
nameDir = obj.value("type_tag").toString();//得到視頻文件所在的文件夾
if(!NameEntry.isEmpty() && !nameDir.isEmpty())
return true;
return false;
}
5.運行結果,成功得到視頻
6.總結,整體程序比較簡單,先是找到entry.json文件進行解析得到視頻文件名和視頻所在的文件夾名,然後再在視頻文件夾下找到視頻文件,利用視頻文件名和自定義的文件存放的路徑爲新的名字,對其進行重命名。代碼比較囉嗦,沒有好的容錯率和可移植性。學習,共勉。