原理
使用windows的命令行的copy命令来合并
copy /b 0+1+2+3 new.ts
分析缓存目录结构,发现都是一个m3u8文件带一个同名文件夹
所以分析m3u8并把原来的路径换成这个缓存文件夹路径并按顺序合并即可。
其中碰到的难点是Qprocess在windows不好使,索性直接存成.bat批处理文件再执行
还有就是中文问题,具体在代码里都说了。
代码 (环境Qt5.7.0)
这是mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QStringList getfiles(const QString &dir_path);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
这是mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextCodec>
#include <QDebug>
#include <QFileDialog>
#include <QDirIterator>
#include <QProcess>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QTextCodec>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QString a = QFileDialog::getExistingDirectory(this,"选择文件夹","");
if(a.isEmpty()) {QMessageBox::warning(this,"注意","请选择一个合法目录!"); return;}
QStringList aa = getfiles(a);
//过滤后缀
for(int i=0 ; i<aa.count() ;i++){
if(!aa.at(i).contains(".m3u8"))
{
aa[i].clear();
}
}
aa.removeAll("");
ui->comboBox->addItems(aa);
}
//递归遍历所有文件
QStringList MainWindow::getfiles(const QString &dir_path)
{
QStringList get_files;
QDir dir(dir_path);
if(!dir.exists())
{
qDebug() << "it is not true dir_path";
}
/*设置过滤参数,QDir::NoDotAndDotDot表示不会去遍历上层目录*/
QDirIterator dir_iterator(dir_path,QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot,QDirIterator::Subdirectories);
while(dir_iterator.hasNext())
{
dir_iterator.next();
QFileInfo file_info = dir_iterator.fileInfo();
QString files = file_info.absoluteFilePath();
get_files.append(files);
}
return get_files;
}
//开始转换
void MainWindow::on_pushButton_2_clicked()
{
QString FileName = ui->comboBox->currentText();
QFileInfo fileinfo = QFileInfo(FileName);
QStringList lines1,lines2;//1文件源内容;2过滤出的有效行参数
///解析m3u8读文件
QFile file(FileName);
if( file.open(QIODevice::ReadOnly) )
{
QTextStream in(&file);
in.setCodec("UTF-8");
while ( !in.atEnd() )
{
QString line = in.readLine();
lines1 << line;
file.close();
}
}
else{
return;
}
//找到所在目录
QString floder;
///排序,返回顺序的Qstringlist文件名
for(int i=0 ; i<lines1.count() ;i++){
if(lines1.at(i).contains("/storage"))//包含某共同目录
{
QString temp = lines1.at(i);
//更换路径
temp.replace("/storage/emulated/0/Quark/Download/","");
floder = fileinfo.absolutePath() + "/" + temp.split("/").first();
temp = temp.split("/").last();
temp.insert(0,"\"");
temp.append("\"");
temp.append("+ ");
lines2<<temp;
}
}
lines2.last().replace("+","");
///命令行组装
QStringList args;
//切目录
args <<"cd"<<floder<<"\n";
//复制指令
args <<"copy /b ";
for(int i=0;i<lines2.size();i++){
QString temmm = lines2.at(i);
args<< temmm;
}
QString objFilename = fileinfo.fileName().replace(".m3u8",".ts") ;
objFilename = QString("%1%2%3").arg("\"").arg(objFilename).arg("\"");
//QStringLiteral();
args<<objFilename;
args<<"\n";
//复制目标视频到指定位置
args <<"copy"<<objFilename<<"\"C:\\Users\\surface\\Desktop\\cache\\\"";//必须用\这种斜杠,不然windows不认-cq20220309
//删除目录
// args<<"del c:\a\b*.txt";
QString process = args.join(" ");//对每个参数加空格
qDebug()<<process;
//写命令
// QTextCodec *codec = QTextCodec::codecForLocale();
QTextCodec *codec = QTextCodec::codecForName("GBK");
QFile note("./temp.bat");
note.remove();//删除旧的
if(note.open(QIODevice::ReadWrite | QIODevice::Text)){
QByteArray encodedString = codec->fromUnicode(process);
note.write(encodedString);
note.close();
}
///执行命令行
QProcess p;
p.start("./temp.bat" );//输出改名
p.waitForStarted();
p.waitForFinished();
qDebug()<<QString::fromLocal8Bit(p.readAllStandardOutput()); //获得输出
ui->textBrowser->append(QString::fromLocal8Bit(p.readAllStandardOutput()));
//命令行拼接-- copy /b 0+1+2+3 new.ts
//下一条处理
if(ui->comboBox->currentIndex()+1 == ui->comboBox->count()){
QMessageBox::information(this,"已经完成了","到底了");
return;
}
ui->comboBox->setCurrentIndex(ui->comboBox->currentIndex()+1);
}
这是ui