Qt5-将手机上B站下载的视频提取到到电脑上并批量移动到指定文件夹和重命名

本人喜欢在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文件进行解析得到视频文件名和视频所在的文件夹名,然后再在视频文件夹下找到视频文件,利用视频文件名和自定义的文件存放的路径为新的名字,对其进行重命名。代码比较啰嗦,没有好的容错率和可移植性。学习,共勉。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章