qiushang 2 月之前
父節點
當前提交
7128d5c73d
共有 8 個文件被更改,包括 345 次插入65 次删除
  1. 二進制
      bin/ia32/ffmpeg.exe
  2. 二進制
      bin/ia32/ffplay.exe
  3. 二進制
      bin/ia32/ffprobe.exe
  4. 二進制
      bin/x64/ffmpeg.exe
  5. 3 3
      nsis/test.nsi
  6. 1 1
      package.json
  7. 2 2
      src/main/index.js
  8. 339 59
      src/renderer/components/home.vue

二進制
bin/x64/ffprobe.exe → bin/ia32/ffmpeg.exe


二進制
bin/ia32/ffplay.exe


二進制
bin/x64/ffplay.exe → bin/ia32/ffprobe.exe


二進制
bin/x64/ffmpeg.exe


+ 3 - 3
nsis/test.nsi

@@ -1,16 +1,16 @@
 # ====================== 自定义宏 产品信息==============================
 !define PRODUCT_MID        		    "EkoFCqqaUJXy"
-!define PRODUCT_VERSION        		"2.0.6.0"
+!define PRODUCT_VERSION        		"2.0.6.1"
 !define PRODUCT_NAME           		"星优视频解析下载器"
 !define INSTALL_OUTPUT_NAME    		"XYCaptureVideo_XY.exe" 
 !define EXE_NAME               		"XYCaptureVideo.exe"
 !define PRODUCT_PATHNAME           	"XYCaptureVideo"     #安装卸载项用到的KEY,注册表
 !define INSTALL_APPEND_PATH         "XYCaptureVideo"     #安装路径追加的名称 
-!define APP_DOWNLOAD_URL    		"https://xy.xingyousoft.com/soft/XYCaptureVideo/lastest2.0.6.0.7z"
+!define APP_DOWNLOAD_URL    		"https://xy.xingyousoft.com/soft/XYCaptureVideo/lastest2.0.6.1.7z"
 !define PRODUCT_PUBLISHER      	    "苏州星优办公软件有限公司"
 !define PRODUCT_LEGAL          	    "苏州星优办公软件有限公司"
 !define STATISTICS_url              "https://www.xingyousoft.com/api/index/user_log"   # 统计网址
-!define UNINSTALL_url               "https://xy.xingyousoft.com/soft/XYCaptureVideo/uninstallWeb/?v=2.0.6.0"   # 接卸优惠网址
+!define UNINSTALL_url               "https://xy.xingyousoft.com/soft/XYCaptureVideo/uninstallWeb/?v=2.0.6.1"   # 接卸优惠网址
 
 # ====================== 自定义宏 安装信息==============================
 !define INSTALL_7Z_NAME 	   		"app.7z"

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 	"name": "XYCaptureVideo",
-	"version": "2.0.6.0",
+	"version": "2.0.6.1",
 	"author": "苏州星优办公软件有限公司",
 	"description": "An electron-vue project",
 	"license": "captureVideo",

+ 2 - 2
src/main/index.js

@@ -46,8 +46,8 @@ function createWindow() {
 	 * Initial window options
 	 */
 	mainWindow = new BrowserWindow({
-		width: 1100,
-		minWidth: 1100,
+		width: 1150,
+		minWidth: 1150,
 		height: 760,
 		minHeight: 760,
 		show: false,

+ 339 - 59
src/renderer/components/home.vue

@@ -41,10 +41,11 @@
 							<el-row type="flex" justify="space-between">
 								<div>
 									<h4 style="display: inline-block;">
-										视频信息
+										解析结果
 									</h4>
 									
-									<el-button @click="mergeClick()" size="small" :disabled="bUrl" title="解析B站网址后启用">B站音视频合并</el-button>
+									<el-button @click="mergeClick()" size="small" :disabled="bUrl" title="解析B站网址后启用">合并下载</el-button>
+									<el-link @click="mergeClick(true)" :disabled="bUrl" type="info" style="margin: 0 10px;">手动合并</el-link>
 								</div>
 								<el-row type="flex" style="align-items: center;">
 									<div class="set-item">
@@ -56,54 +57,185 @@
 									</div>
 								</el-row>
 							</el-row>
-							<vxe-table ref="xTable" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :loading="tabLoading" :row-config="{isHover: true}" 
-								:loading-config="{icon: 'vxe-icon-indicator roll', text: '加载中...'}" :data="videoList" :scroll-y="{enabled: true}">
-								<vxe-column field="title" title="标题">
-									<template #default="{ row }">
-										{{row.title}}[{{row.format_id}}]
-									</template>
-								</vxe-column>
-								<vxe-column field="ext" title="扩展名" width="70"></vxe-column>
-								<vxe-column field="resolution" title="分辨率" width="100"></vxe-column>
-								<vxe-column field="fps" title="帧率" width="60"></vxe-column>
-								<vxe-column field="filesize" title="大小" width="90">
-									<template #default="{ row }">
-										<span v-if="row.filesize">{{$utils.handleSize(row.filesize)}}</span>
-										<span v-else-if="row.filesize_approx">{{$utils.handleSize(row.filesize_approx)}}</span>
-									</template>
-								</vxe-column>
-								<vxe-column field="vcodec" title="视频编码" width="120"></vxe-column>
-								<vxe-column field="acodec" title="音频编码" width="120"></vxe-column>
-								<vxe-column field="status" title="状态" width="140">
-									<template #default="{ row }">
-										<template v-if="row.status == '1'">
-											<i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
-											<span>待操作</span>
+							<div style="display: flex; flex-wrap: nowrap;justify-content: space-between;height: calc(100% - 60px);">
+								<vxe-table v-show="bUrl" style="width: 100%;" ref="xTable" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :loading="tabLoading" :row-config="{isHover: true}"
+									:loading-config="{icon: 'vxe-icon-indicator roll', text: '加载中...'}" :data="videoList" :scroll-y="{enabled: true}">
+									<vxe-column field="title" title="标题">
+										<template #default="{ row }">
+											{{row.title}}[{{row.format_id}}]
 										</template>
-										<template v-if="row.status == '2'">
-											<i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
-											<span>下载中.. <span v-if="row.percent">{{row.percent}}%</span></span>
+									</vxe-column>
+									<vxe-column field="ext" title="扩展名" width="70"></vxe-column>
+									<vxe-column field="resolution" title="分辨率" width="100"></vxe-column>
+									<vxe-column field="fps" title="帧率" width="60"></vxe-column>
+									<vxe-column field="filesize" title="大小" width="90">
+										<template #default="{ row }">
+											<span v-if="row.filesize">{{$utils.handleSize(row.filesize)}}</span>
+											<span v-else-if="row.filesize_approx">{{$utils.handleSize(row.filesize_approx)}}</span>
 										</template>
-										<template v-if="row.status == '3'">
-											<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
-											<span>下载完成</span>
+									</vxe-column>
+									<vxe-column field="vcodec" title="视频编码" width="120"></vxe-column>
+									<vxe-column field="acodec" title="音频编码" width="120"></vxe-column>
+									<vxe-column field="status" title="状态" width="140">
+										<template #default="{ row }">
+											<template v-if="row.status == '1'">
+												<i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
+												<span>待操作</span>
+											</template>
+											<template v-if="row.status == '2'">
+												<i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
+												<span>下载中.. <span v-if="row.percent">{{row.percent}}%</span></span>
+											</template>
+											<template v-if="row.status == '3'">
+												<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
+												<span>下载完成</span>
+											</template>
+											<template v-if="row.status == '4'">
+												<i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
+												<span>下载出错,请重试!</span>
+											</template>
 										</template>
-										<template v-if="row.status == '4'">
-											<i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
-											<span>下载出错,请重试!</span>
+									</vxe-column>
+									<vxe-column title="操作" width="100">
+										<template #default="{ row, rowIndex }">
+											<!-- <el-button v-if="row.urlList && row.urlList.length > 0" type="danger" size="mini" plain @click="copy(rowIndex)">复制</el-button> -->
+											<el-button :loading="row.loading" type="danger" size="mini" plain @click="downloadVideo(rowIndex)">下载</el-button>
 										</template>
-									</template>
-								</vxe-column>
-								<vxe-column title="操作" width="100">
-									<template #default="{ row, rowIndex }">
-										<!-- <el-button v-if="row.urlList && row.urlList.length > 0" type="danger" size="mini" plain @click="copy(rowIndex)">复制</el-button> -->
-										<el-button :loading="row.loading" type="danger" size="mini" plain @click="downloadVideo(rowIndex)">下载</el-button>
-									</template>
-								</vxe-column>
-							</vxe-table>
+									</vxe-column>
+								</vxe-table>
+								
+								<!-- b站视频 -->
+								<vxe-table v-show="!bUrl" style="width: 55%;" ref="xTable2" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :loading="tabLoading" :row-config="{isHover: true}"
+									:loading-config="{icon: 'vxe-icon-indicator roll', text: '加载中...'}" :radio-config="{ highlight: true }" @radio-change="handleVideoSelect" :data="biliVideoList" :scroll-y="{enabled: true}">
+									<vxe-column type="radio" width="30"></vxe-column>
+									<vxe-column field="title" title="视频ID">
+										<template #default="{ row }">
+											{{row.format_id}}
+										</template>
+									</vxe-column>
+									<vxe-column field="resolution" title="分辨率" width="90"></vxe-column>
+									<vxe-column field="filesize" title="大小" width="90">
+										<template #default="{ row }">
+											<span v-if="row.filesize">{{$utils.handleSize(row.filesize)}}</span>
+											<span v-else-if="row.filesize_approx">{{$utils.handleSize(row.filesize_approx)}}</span>
+										</template>
+									</vxe-column>
+									
+									<vxe-column field="status" title="状态" width="130">
+										<template #default="{ row }">
+											<template v-if="row.status == '1'">
+												<i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
+												<span>待操作</span>
+											</template>
+											<template v-if="row.status == '2'">
+												<i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
+												<span>下载中.. <span v-if="row.percent">{{row.percent}}%</span></span>
+											</template>
+											<template v-if="row.status == '3'">
+												<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
+												<span>下载完成</span>
+											</template>
+											<template v-if="row.status == '4'">
+												<i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
+												<span>下载出错,请重试!</span>
+											</template>
+										</template>
+									</vxe-column>
+									<vxe-column title="操作" width="165">
+										<template #default="{ row, rowIndex }">
+											<el-button size="mini" plain @click="biliDetail(row)">详情</el-button>
+											<el-button :loading="row.loading" type="danger" size="mini" plain @click="downloadVideo(rowIndex, true, 'biliVideo')">下载</el-button>
+										</template>
+									</vxe-column>
+								</vxe-table>
+								
+								<!-- b站音频 -->
+								<vxe-table v-show="!bUrl" ref="xTable3" style="width: 44%;" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :loading="tabLoading" :row-config="{isHover: true}"
+									:loading-config="{icon: 'vxe-icon-indicator roll', text: '加载中...'}" :radio-config="{ highlight: true }" @radio-change="handleAudioSelect" :data="biliAudioList" :scroll-y="{enabled: true}">
+									<vxe-column type="radio" width="30"></vxe-column>
+									<vxe-column field="title" title="音频ID">
+										<template #default="{ row }">
+											{{row.format_id}}
+										</template>
+									</vxe-column>
+									<vxe-column field="filesize" title="大小" width="90">
+										<template #default="{ row }">
+											<span v-if="row.filesize">{{$utils.handleSize(row.filesize)}}</span>
+											<span v-else-if="row.filesize_approx">{{$utils.handleSize(row.filesize_approx)}}</span>
+										</template>
+									</vxe-column>
+									<vxe-column field="status" title="状态" width="130">
+										<template #default="{ row }">
+											<template v-if="row.status == '1'">
+												<i class="el-icon-info" style="font-size: 16px; color: #999;"></i>
+												<span>待操作</span>
+											</template>
+											<template v-if="row.status == '2'">
+												<i class="el-icon-loading" style="font-size: 16px; color: #999;"></i>
+												<span>下载中.. <span v-if="row.percent">{{row.percent}}%</span></span>
+											</template>
+											<template v-if="row.status == '3'">
+												<i class="el-icon-success" style="font-size: 16px; color: #19be6b;"></i>
+												<span>下载完成</span>
+											</template>
+											<template v-if="row.status == '4'">
+												<i class="el-icon-error" style="font-size: 16px; color: #ed4014;"></i>
+												<span>下载出错,请重试!</span>
+											</template>
+										</template>
+									</vxe-column>
+									<vxe-column title="操作" width="165">
+										<template #default="{ row, rowIndex }">
+											<el-button size="mini" plain @click="biliDetail(row)">详情</el-button>
+											<el-button :loading="row.loading" type="danger" size="mini" plain @click="downloadVideo(rowIndex, true, 'biliAudio')">下载</el-button>
+										</template>
+									</vxe-column>
+								</vxe-table>
+								
+								
+							</div>
+
 						</div>
 					</div>
 				</template>
+
+				<!-- B站音视频信息展示框 -->
+				<el-dialog title="文件信息" :visible.sync="infoModal" width="420px">
+					<div class="member-model">
+						<div class="handle-item" v-if="biliInfo.title">
+							<label class="handle-label">名称:</label>
+							<span style="color: #999;">{{biliInfo.title}}[{{biliInfo.format_id}}]</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.format">
+							<label class="handle-label">标记:</label>
+							<span style="color: #999;">{{biliInfo.format}}</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.ext">
+							<label class="handle-label">扩展名:</label>
+							<span style="color: #999;">{{biliInfo.ext}}</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.resolution">
+							<label class="handle-label">分辨率:</label>
+							<span style="color: #999;">{{biliInfo.resolution}}</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.fps">
+							<label class="handle-label">帧率:</label>
+							<span style="color: #999;">{{biliInfo.fps}}</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.filesize">
+							<label class="handle-label">大小:</label>
+							<span style="color: #999;">{{biliInfo.filesize}}</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.vcodec">
+							<label class="handle-label">视频编码:</label>
+							<span style="color: #999;">{{biliInfo.vcodec}}</span>
+						</div>
+						<div class="handle-item" v-if="biliInfo.acodec">
+							<label class="handle-label">音频编码:</label>
+							<span style="color: #999;">{{biliInfo.acodec}}</span>
+						</div>
+					</div>
+				</el-dialog>
 				
 				<!-- B站音视频合并提示框 -->
 				<el-dialog title="B站音视频合并" :visible.sync="mergeModal" width="420px" :close-on-click-modal="false" :close-on-press-escape="false">
@@ -236,6 +368,7 @@
 		},
 		data() {
 			return {
+				infoModal: false,
 				selectIndex: -1,
 				usageTimes: 3,
 				tipsModal: false,
@@ -249,12 +382,17 @@
 					videoDuration: '',
 					audioDuration: '',
 				},
-
+				
+				biliInfo: {},
 				formatUrl: '',
 				downloadUrl: '', //格式化之后的dtp下载地址
 				tabLoading: false,
 				videoInfo: {},
 				videoList: [],
+				biliAudioList: [],
+				biliVideoList: [],
+				biliVideoIndex: -1,
+				biliAudioIndex: -1,
 				productName: pjson.softInfo.softName,
 				imgUrl: this.$api.imgUrl,
 				imgSrc: '',
@@ -449,9 +587,142 @@
 					});
 				}
 			},
-			mergeClick(){
-				this.mergeModal = true;
+			mergeClick(flag){
+				if(flag){
+					this.mergeModal = true;
+					this.bVideoInfo.title = this.videoList[0].title;
+					return false;
+				}
 				this.bVideoInfo.title = this.videoList[0].title;
+				if(this.biliVideoIndex < 0 || this.biliAudioIndex < 0){
+					this.$message.error('请先选择需要下载合并的视频或音频');
+					return false;
+				}
+				
+				this.tabLoading = true;
+				if (!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName + separator + 'b站合并文件')) {
+					fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName + separator + 'b站合并文件');
+				}
+				
+				let item = this.biliVideoList[this.biliVideoIndex];
+				let audioItem = this.biliAudioList[this.biliAudioIndex];
+				let newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + 'b站合并文件';
+				let videoTitle = 'b站视频.' + item.ext; //'%(title).50s['+item.format_id+'].%(ext)s';
+				let audioTitle = 'b站音频.' + audioItem.ext; //'%(title).50s['+audioItem.format_id+'].%(ext)s';
+				let params = [
+					'-f',
+					item.format_id,
+					'--force-overwrites',
+					'-o',
+					newPath + separator + videoTitle,
+					this.downloadUrl
+				];
+				item.status = '2';
+				item.loading = true;
+				this.$forceUpdate();
+				electronApi.spawnExec(['dlp.exe', ...params],{
+					stdout:(data) =>{
+						let str = data.toString();
+						const regexDuration = /[download].*? (.*?)%/;
+						const res = regexDuration.exec(str);
+						if(res && res[1]){
+							item.percent = res[1];
+							this.$forceUpdate();
+						}
+					}
+				}).then(res => {
+					let outData = res.stdout ? res.stdout.toString() : '{}';
+					item.status = '3';
+					item.loading = false;
+					this.$forceUpdate();
+					
+					 // 视频下载成功,开始下载音频文件
+					let params = [
+						'-f',
+						audioItem.format_id,
+						'--force-overwrites',
+						'-o',
+						newPath + separator + audioTitle,
+						this.downloadUrl
+					];
+					audioItem.status = '2';
+					audioItem.loading = true;
+					this.$forceUpdate();
+					electronApi.spawnExec(['dlp.exe', ...params],{
+						stdout:(data) =>{
+							let str = data.toString();
+							const regexDuration = /[download].*? (.*?)%/;
+							const res = regexDuration.exec(str);
+							if(res && res[1]){
+								audioItem.percent = res[1];
+								this.$forceUpdate();
+							}
+						}
+					}).then(res => {
+						let outData = res.stdout ? res.stdout.toString() : '{}';
+						audioItem.status = '3';
+						audioItem.loading = false;
+						this.$forceUpdate();
+						
+						let outPath = this.downloadDir + separator + pjson.softInfo.softName;
+						let params = [
+							'ffmpeg.exe',
+							'-i',
+							newPath + separator + videoTitle,
+							'-i',
+							newPath + separator + audioTitle,
+							'-c',
+							'copy',
+							outPath + separator + item.title + '.mp4',
+							'-hide_banner',
+							'-y'
+						];
+						const regexTime = /time=(.*?) bitrate/;
+						electronApi.spawnExec(params,{
+							stderr:(data) =>{
+								
+							}
+						}).then(res => {
+							this.tabLoading = false;
+							this.$message({message: '恭喜你,合并下载已完成!', type: 'success'});
+							electronApi.call('showItemInfolder',[this.downloadDir + separator + pjson.softInfo.softName +'\\tty.tty']);
+						}).catch(err =>{
+							this.tabLoading = false;
+							this.$notify.error({
+								title: '合并失败',
+								message: '视频参数有误,请重试! ',
+							});
+						})
+						
+						
+					}).catch(err =>{
+						item.status = '4';
+						item.loading = false;
+						this.$forceUpdate();
+						// console.log(err);
+					})
+					
+				}).catch(err =>{
+					item.status = '4';
+					item.loading = false;
+					this.$forceUpdate();
+					// console.log(err);
+				})
+				
+				
+				
+				
+				
+			},
+			biliDetail(row){
+				this.biliInfo = row;
+				this.infoModal = true;
+			},
+			handleVideoSelect({ row, rowIndex }){
+				this.biliVideoIndex = rowIndex;
+			},
+			handleAudioSelect({ row, rowIndex }){
+				this.biliAudioIndex = rowIndex;
 			},
 			// b站视频合并
 			mergeVideo(){
@@ -535,11 +806,6 @@
 						let info = res.stdout ? res.stdout.toString() : '{formats: []}';
 						this.videoInfo = JSON.parse(info);
 						this.videoList = this.videoInfo.formats || [];
-						this.videoList.map(item => {
-							item.title = this.videoInfo.title,
-							item.status = '1';
-						})
-						
 						const bregex = /https:\/\/.*?.bilibili.com/;
 						const bres = bregex.exec(formatUrl);
 						if(bres && bres.length > 0){ //b站的视频
@@ -547,6 +813,21 @@
 						}else{
 							this.bUrl = true;
 						}
+						this.biliAudioList = [];
+						this.biliAudioIndex = -1;
+						this.biliVideoList = [];
+						this.biliVideoIndex = -1;
+						this.videoList.map(item => {
+							item.title = this.videoInfo.title,
+							item.status = '1';
+							if(!this.bUrl){ // b站的视频
+								if(item.resolution.indexOf('audio') > -1 || item.audio_ext != 'none'){
+									this.biliAudioList.push(item);
+								}else{
+									this.biliVideoList.push(item);
+								}
+							}
+						})
 					}).catch(err =>{
 						this.parseLoading = false;
 						this.tabLoading = false;
@@ -575,13 +856,6 @@
 			},
 			// 点击复制
 			copy(index){
-				// let authority = this.$refs.headerRef.authority.isAuthority;
-				// if (!authority) {
-				// 	this.tipsModal = true;
-				// 	this.tipsDesc = '暂无下载权限,请开通VIP会员使用';
-				// 	return false;
-				// }
-				
 				this.commonUrl = '';
 				this.thunderUrl = [];
 				let tag = this.videoList[index].tag;
@@ -613,7 +887,7 @@
 			},
 			
 			// 点击下载视频
-			async downloadVideo(index, flag){
+			async downloadVideo(index, flag, list){
 				this.selectIndex = index;
 				let authority = this.$refs.headerRef.authority.isAuthority;
 				if (!authority) {
@@ -627,6 +901,12 @@
 					this.copy(index);
 				}else{
 					let item = this.videoList[index];
+					if(list == 'biliVideo'){
+						item = this.biliVideoList[index];
+					}else if(list == 'biliAudio'){
+						item = this.biliAudioList[index];
+					}
+					
 					if (!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)) {
 						fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
 					}