parent
8809fe2ace
commit
fdfe35d71e
|
|
@ -32,7 +32,6 @@ func init() {
|
|||
rootCmd.Flags().BoolVarP(&gRunReq.Insecure, "Insecure", "", false, "是否允许不安全的请求")
|
||||
rootCmd.Flags().StringVarP(&gRunReq.SaveDir, "SaveDir", "d", "", "文件保存路径(默认为当前路径)")
|
||||
rootCmd.Flags().StringVarP(&gRunReq.FileName, "FileName", "f", "", "文件名")
|
||||
rootCmd.Flags().BoolVarP(&gRunReq.UserFfmpegMerge, "UserFfmpegMerge", "", true, "使用ffmpeg合并分段视频")
|
||||
rootCmd.Flags().IntVarP(&gRunReq.SkipTsCountFromHead, "SkipTsCountFromHead", "", 0, "跳过前面几个ts")
|
||||
}
|
||||
|
||||
|
|
|
|||
66
download.go
66
download.go
|
|
@ -52,7 +52,6 @@ type RunDownload_Req struct {
|
|||
Insecure bool `json:"-"` // "是否允许不安全的请求(默认为false)"
|
||||
SaveDir string `json:"-"` // "文件保存路径(默认为当前路径)"
|
||||
FileName string `json:"-"` // 文件名
|
||||
UserFfmpegMerge bool `json:",omitempty"` // 使用ffmpeg合并分段视频
|
||||
SkipTsCountFromHead int `json:",omitempty"` // 跳过前面几个ts
|
||||
}
|
||||
|
||||
|
|
@ -99,12 +98,10 @@ func RunDownload(req RunDownload_Req) (resp RunDownload_Resp) {
|
|||
}
|
||||
}
|
||||
var ffmpegExe string
|
||||
if req.UserFfmpegMerge {
|
||||
ffmpegExe, err = goffmpeg.SetupFfmpeg()
|
||||
if err != nil {
|
||||
resp.ErrMsg = "SetupFfmpeg error: " + err.Error()
|
||||
return resp
|
||||
}
|
||||
ffmpegExe, err = goffmpeg.SetupFfmpeg()
|
||||
if err != nil {
|
||||
resp.ErrMsg = "SetupFfmpeg error: " + err.Error()
|
||||
return resp
|
||||
}
|
||||
host, err := getHost(req.M3u8Url, "apiv2")
|
||||
if err != nil {
|
||||
|
|
@ -171,30 +168,21 @@ func RunDownload(req RunDownload_Req) (resp RunDownload_Resp) {
|
|||
}
|
||||
var tmpOutputName string
|
||||
var contentHash string
|
||||
if req.UserFfmpegMerge {
|
||||
tmpOutputName = filepath.Join(downloadDir, "all.merge.mp4")
|
||||
err = goffmpeg.MergeMultiToSingleMp4(goffmpeg.MergeMultiToSingleMp4_Req{
|
||||
FfmpegExePath: ffmpegExe,
|
||||
TsFileList: tsFileList,
|
||||
OutputMp4: tmpOutputName,
|
||||
ProgressCh: nil,
|
||||
})
|
||||
if err != nil {
|
||||
resp.ErrMsg = "合并错误: " + err.Error()
|
||||
return resp
|
||||
}
|
||||
contentHash = getFileSha256(tmpOutputName)
|
||||
if contentHash == "" {
|
||||
resp.ErrMsg = "无法计算摘要信息: " + tmpOutputName
|
||||
return resp
|
||||
}
|
||||
} else {
|
||||
tmpOutputName = filepath.Join(downloadDir, "all.merge.ts")
|
||||
contentHash, err = mergeTsFileList_Raw(tsFileList, tmpOutputName)
|
||||
if err != nil {
|
||||
resp.ErrMsg = "合并错误: " + err.Error()
|
||||
return resp
|
||||
}
|
||||
tmpOutputName = filepath.Join(downloadDir, "all.merge.mp4")
|
||||
err = goffmpeg.MergeMultiToSingleMp4(goffmpeg.MergeMultiToSingleMp4_Req{
|
||||
FfmpegExePath: ffmpegExe,
|
||||
TsFileList: tsFileList,
|
||||
OutputMp4: tmpOutputName,
|
||||
ProgressCh: nil,
|
||||
})
|
||||
if err != nil {
|
||||
resp.ErrMsg = "合并错误: " + err.Error()
|
||||
return resp
|
||||
}
|
||||
contentHash = getFileSha256(tmpOutputName)
|
||||
if contentHash == "" {
|
||||
resp.ErrMsg = "无法计算摘要信息: " + tmpOutputName
|
||||
return resp
|
||||
}
|
||||
var name string
|
||||
for idx := 0; ; idx++ {
|
||||
|
|
@ -203,18 +191,10 @@ func RunDownload(req RunDownload_Req) (resp RunDownload_Resp) {
|
|||
idxS = strings.Repeat("0", 4-len(idxS)) + idxS
|
||||
}
|
||||
idxS = "_" + idxS
|
||||
if req.UserFfmpegMerge {
|
||||
if idx == 0 {
|
||||
name = filepath.Join(req.SaveDir, req.FileName+".mp4")
|
||||
} else {
|
||||
name = filepath.Join(req.SaveDir, req.FileName+idxS+".mp4")
|
||||
}
|
||||
} else { // 直接合并的就是ts,不是mp4
|
||||
if idx == 0 {
|
||||
name = filepath.Join(req.SaveDir, req.FileName+".ts")
|
||||
} else {
|
||||
name = filepath.Join(req.SaveDir, req.FileName+idxS+".ts")
|
||||
}
|
||||
if idx == 0 {
|
||||
name = filepath.Join(req.SaveDir, req.FileName+".mp4")
|
||||
} else {
|
||||
name = filepath.Join(req.SaveDir, req.FileName+idxS+".mp4")
|
||||
}
|
||||
if !isFileExists(name) {
|
||||
resp.SaveFileTo = name
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
//BuildCliBinary() // 编译二进制
|
||||
CreateLibForQtUi() // 创建Qt需要使用的.a库文件
|
||||
BuildCliBinary() // 编译二进制
|
||||
CreateLibForQtUi() // 创建Qt需要使用的.a库文件
|
||||
}
|
||||
|
||||
func BuildCliBinary() {
|
||||
|
|
@ -25,23 +25,10 @@ func BuildCliBinary() {
|
|||
Ext string
|
||||
}
|
||||
var list = []buildCfg{
|
||||
{
|
||||
GOOS: "windows",
|
||||
GOARCH: "amd64",
|
||||
Ext: ".exe",
|
||||
},
|
||||
{
|
||||
GOOS: "linux",
|
||||
GOARCH: "amd64",
|
||||
},
|
||||
{
|
||||
GOOS: "linux",
|
||||
GOARCH: "386",
|
||||
},
|
||||
{
|
||||
GOOS: "linux",
|
||||
GOARCH: "arm64",
|
||||
},
|
||||
{
|
||||
GOOS: "linux",
|
||||
GOARCH: "arm",
|
||||
|
|
@ -52,7 +39,7 @@ func BuildCliBinary() {
|
|||
},
|
||||
}
|
||||
for _, cfg := range list {
|
||||
name := "m3u8d_cli_v1.0_" + cfg.GOOS + "_" + cfg.GOARCH + cfg.Ext
|
||||
name := "m3u8d_cli_v1.1_" + cfg.GOOS + "_" + cfg.GOARCH + cfg.Ext
|
||||
cmd := exec.Command("go", "build", "-o", filepath.Join(wd, "bin", name))
|
||||
cmd.Dir = filepath.Join(wd, "cmd")
|
||||
cmd.Env = append(os.Environ(), "GOOS="+cfg.GOOS)
|
||||
|
|
@ -78,4 +65,4 @@ func CreateLibForQtUi() {
|
|||
ctx.Generate1(m3u8d.GetProgress)
|
||||
ctx.Generate1(m3u8d.GetWd)
|
||||
ctx.MustCreateAmd64LibraryInDir("m3u8d-qt")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -82,54 +82,53 @@ RunDownload_Resp RunDownload(RunDownload_Req in0){
|
|||
std::string in;
|
||||
{
|
||||
{
|
||||
uint32_t tmp19 = in0.M3u8Url.length();
|
||||
char tmp20[4];
|
||||
tmp20[0] = (uint32_t(tmp19) >> 24) & 0xFF;
|
||||
tmp20[1] = (uint32_t(tmp19) >> 16) & 0xFF;
|
||||
tmp20[2] = (uint32_t(tmp19) >> 8) & 0xFF;
|
||||
tmp20[3] = (uint32_t(tmp19) >> 0) & 0xFF;
|
||||
in.append(tmp20, 4);
|
||||
uint32_t tmp18 = in0.M3u8Url.length();
|
||||
char tmp19[4];
|
||||
tmp19[0] = (uint32_t(tmp18) >> 24) & 0xFF;
|
||||
tmp19[1] = (uint32_t(tmp18) >> 16) & 0xFF;
|
||||
tmp19[2] = (uint32_t(tmp18) >> 8) & 0xFF;
|
||||
tmp19[3] = (uint32_t(tmp18) >> 0) & 0xFF;
|
||||
in.append(tmp19, 4);
|
||||
in.append(in0.M3u8Url);
|
||||
}
|
||||
{
|
||||
uint32_t tmp21 = in0.HostType.length();
|
||||
char tmp22[4];
|
||||
tmp22[0] = (uint32_t(tmp21) >> 24) & 0xFF;
|
||||
tmp22[1] = (uint32_t(tmp21) >> 16) & 0xFF;
|
||||
tmp22[2] = (uint32_t(tmp21) >> 8) & 0xFF;
|
||||
tmp22[3] = (uint32_t(tmp21) >> 0) & 0xFF;
|
||||
in.append(tmp22, 4);
|
||||
uint32_t tmp20 = in0.HostType.length();
|
||||
char tmp21[4];
|
||||
tmp21[0] = (uint32_t(tmp20) >> 24) & 0xFF;
|
||||
tmp21[1] = (uint32_t(tmp20) >> 16) & 0xFF;
|
||||
tmp21[2] = (uint32_t(tmp20) >> 8) & 0xFF;
|
||||
tmp21[3] = (uint32_t(tmp20) >> 0) & 0xFF;
|
||||
in.append(tmp21, 4);
|
||||
in.append(in0.HostType);
|
||||
}
|
||||
in.append((char*)(&in0.Insecure), 1);
|
||||
{
|
||||
uint32_t tmp23 = in0.SaveDir.length();
|
||||
char tmp24[4];
|
||||
tmp24[0] = (uint32_t(tmp23) >> 24) & 0xFF;
|
||||
tmp24[1] = (uint32_t(tmp23) >> 16) & 0xFF;
|
||||
tmp24[2] = (uint32_t(tmp23) >> 8) & 0xFF;
|
||||
tmp24[3] = (uint32_t(tmp23) >> 0) & 0xFF;
|
||||
in.append(tmp24, 4);
|
||||
uint32_t tmp22 = in0.SaveDir.length();
|
||||
char tmp23[4];
|
||||
tmp23[0] = (uint32_t(tmp22) >> 24) & 0xFF;
|
||||
tmp23[1] = (uint32_t(tmp22) >> 16) & 0xFF;
|
||||
tmp23[2] = (uint32_t(tmp22) >> 8) & 0xFF;
|
||||
tmp23[3] = (uint32_t(tmp22) >> 0) & 0xFF;
|
||||
in.append(tmp23, 4);
|
||||
in.append(in0.SaveDir);
|
||||
}
|
||||
{
|
||||
uint32_t tmp25 = in0.FileName.length();
|
||||
char tmp26[4];
|
||||
tmp26[0] = (uint32_t(tmp25) >> 24) & 0xFF;
|
||||
tmp26[1] = (uint32_t(tmp25) >> 16) & 0xFF;
|
||||
tmp26[2] = (uint32_t(tmp25) >> 8) & 0xFF;
|
||||
tmp26[3] = (uint32_t(tmp25) >> 0) & 0xFF;
|
||||
in.append(tmp26, 4);
|
||||
uint32_t tmp24 = in0.FileName.length();
|
||||
char tmp25[4];
|
||||
tmp25[0] = (uint32_t(tmp24) >> 24) & 0xFF;
|
||||
tmp25[1] = (uint32_t(tmp24) >> 16) & 0xFF;
|
||||
tmp25[2] = (uint32_t(tmp24) >> 8) & 0xFF;
|
||||
tmp25[3] = (uint32_t(tmp24) >> 0) & 0xFF;
|
||||
in.append(tmp25, 4);
|
||||
in.append(in0.FileName);
|
||||
}
|
||||
in.append((char*)(&in0.UserFfmpegMerge), 1);
|
||||
{
|
||||
char tmp27[4];
|
||||
tmp27[0] = (uint32_t(in0.SkipTsCountFromHead) >> 24) & 0xFF;
|
||||
tmp27[1] = (uint32_t(in0.SkipTsCountFromHead) >> 16) & 0xFF;
|
||||
tmp27[2] = (uint32_t(in0.SkipTsCountFromHead) >> 8) & 0xFF;
|
||||
tmp27[3] = (uint32_t(in0.SkipTsCountFromHead) >> 0) & 0xFF;
|
||||
in.append(tmp27, 4);
|
||||
char tmp26[4];
|
||||
tmp26[0] = (uint32_t(in0.SkipTsCountFromHead) >> 24) & 0xFF;
|
||||
tmp26[1] = (uint32_t(in0.SkipTsCountFromHead) >> 16) & 0xFF;
|
||||
tmp26[2] = (uint32_t(in0.SkipTsCountFromHead) >> 8) & 0xFF;
|
||||
tmp26[3] = (uint32_t(in0.SkipTsCountFromHead) >> 0) & 0xFF;
|
||||
in.append(tmp26, 4);
|
||||
}
|
||||
}
|
||||
char *out = NULL;
|
||||
|
|
@ -139,28 +138,28 @@ RunDownload_Resp RunDownload(RunDownload_Req in0){
|
|||
int outIdx = 0;
|
||||
{
|
||||
{
|
||||
uint32_t tmp28 = 0;
|
||||
uint32_t tmp29 = uint32_t(uint8_t(out[outIdx+0]) << 24);
|
||||
uint32_t tmp30 = uint32_t(uint8_t(out[outIdx+1]) << 16);
|
||||
uint32_t tmp31 = uint32_t(uint8_t(out[outIdx+2]) << 8);
|
||||
uint32_t tmp32 = uint32_t(uint8_t(out[outIdx+3]) << 0);
|
||||
tmp28 = tmp29 | tmp30 | tmp31 | tmp32;
|
||||
uint32_t tmp27 = 0;
|
||||
uint32_t tmp28 = uint32_t(uint8_t(out[outIdx+0]) << 24);
|
||||
uint32_t tmp29 = uint32_t(uint8_t(out[outIdx+1]) << 16);
|
||||
uint32_t tmp30 = uint32_t(uint8_t(out[outIdx+2]) << 8);
|
||||
uint32_t tmp31 = uint32_t(uint8_t(out[outIdx+3]) << 0);
|
||||
tmp27 = tmp28 | tmp29 | tmp30 | tmp31;
|
||||
outIdx+=4;
|
||||
retValue.ErrMsg = std::string(out+outIdx, out+outIdx+tmp28);
|
||||
outIdx+=tmp28;
|
||||
retValue.ErrMsg = std::string(out+outIdx, out+outIdx+tmp27);
|
||||
outIdx+=tmp27;
|
||||
}
|
||||
retValue.IsSkipped = (bool) out[outIdx];
|
||||
outIdx++;
|
||||
{
|
||||
uint32_t tmp33 = 0;
|
||||
uint32_t tmp34 = uint32_t(uint8_t(out[outIdx+0]) << 24);
|
||||
uint32_t tmp35 = uint32_t(uint8_t(out[outIdx+1]) << 16);
|
||||
uint32_t tmp36 = uint32_t(uint8_t(out[outIdx+2]) << 8);
|
||||
uint32_t tmp37 = uint32_t(uint8_t(out[outIdx+3]) << 0);
|
||||
tmp33 = tmp34 | tmp35 | tmp36 | tmp37;
|
||||
uint32_t tmp32 = 0;
|
||||
uint32_t tmp33 = uint32_t(uint8_t(out[outIdx+0]) << 24);
|
||||
uint32_t tmp34 = uint32_t(uint8_t(out[outIdx+1]) << 16);
|
||||
uint32_t tmp35 = uint32_t(uint8_t(out[outIdx+2]) << 8);
|
||||
uint32_t tmp36 = uint32_t(uint8_t(out[outIdx+3]) << 0);
|
||||
tmp32 = tmp33 | tmp34 | tmp35 | tmp36;
|
||||
outIdx+=4;
|
||||
retValue.SaveFileTo = std::string(out+outIdx, out+outIdx+tmp33);
|
||||
outIdx+=tmp33;
|
||||
retValue.SaveFileTo = std::string(out+outIdx, out+outIdx+tmp32);
|
||||
outIdx+=tmp32;
|
||||
}
|
||||
}
|
||||
if (out != NULL) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ struct RunDownload_Req{
|
|||
bool Insecure;
|
||||
std::string SaveDir;
|
||||
std::string FileName;
|
||||
bool UserFfmpegMerge;
|
||||
int32_t SkipTsCountFromHead;
|
||||
};
|
||||
struct RunDownload_Resp{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ void MainWindow::on_pushButton_RunDownload_clicked()
|
|||
ui->lineEdit_FileName->setEnabled(false);
|
||||
ui->lineEdit_SkipTsCountFromHead->setEnabled(false);
|
||||
ui->comboBox_HostType->setEnabled(false);
|
||||
ui->comboBox_OutputFormat->setEnabled(false);
|
||||
ui->pushButton_RunDownload->setEnabled(false);
|
||||
ui->checkBox_Insecure->setEnabled(false);
|
||||
ui->progressBar->setValue(0);
|
||||
|
|
@ -59,7 +58,6 @@ void MainWindow::on_pushButton_RunDownload_clicked()
|
|||
req.Insecure = ui->checkBox_Insecure->isChecked();
|
||||
req.SaveDir = ui->lineEdit_SaveDir->text().toStdString();
|
||||
req.FileName = ui->lineEdit_FileName->text().toStdString();
|
||||
req.UserFfmpegMerge = ui->comboBox_OutputFormat->currentIndex() == 0;
|
||||
req.SkipTsCountFromHead = ui->lineEdit_SkipTsCountFromHead->text().toInt();
|
||||
|
||||
m_syncUi.AddRunFnOn_OtherThread([req, this](){
|
||||
|
|
@ -71,7 +69,6 @@ void MainWindow::on_pushButton_RunDownload_clicked()
|
|||
ui->lineEdit_FileName->setEnabled(true);
|
||||
ui->lineEdit_SkipTsCountFromHead->setEnabled(true);
|
||||
ui->comboBox_HostType->setEnabled(true);
|
||||
ui->comboBox_OutputFormat->setEnabled(true);
|
||||
ui->pushButton_RunDownload->setEnabled(true);
|
||||
ui->checkBox_Insecure->setEnabled(false);
|
||||
ui->pushButton_RunDownload->setText("开始下载");
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>735</width>
|
||||
<height>282</height>
|
||||
<width>747</width>
|
||||
<height>247</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
|
@ -17,26 +17,13 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>m3u8的url</string>
|
||||
<string>HostType</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="lineEdit_M3u8Url"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>保存位置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="lineEdit_SaveDir"/>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="pushButton_SaveDir">
|
||||
<property name="text">
|
||||
|
|
@ -44,6 +31,9 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="lineEdit_SkipTsCountFromHead"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
|
|
@ -58,24 +48,27 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLineEdit" name="lineEdit_SkipTsCountFromHead"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>输出文件格式</string>
|
||||
<string>保存位置</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>HostType</string>
|
||||
<string>m3u8的url</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLineEdit" name="lineEdit_M3u8Url"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="lineEdit_SaveDir"/>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QComboBox" name="comboBox_HostType">
|
||||
<item>
|
||||
<property name="text">
|
||||
|
|
@ -89,20 +82,6 @@
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QComboBox" name="comboBox_OutputFormat">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>mp4格式(使用ffmpeg合并分段视频)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ts格式(直接拼接分段视频)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
|
|
|
|||
Loading…
Reference in New Issue