qiushang 1 year ago
parent
commit
823b284c2e

+ 1 - 1
src/renderer/assets/css/home.scss

@@ -120,7 +120,7 @@ div,p{
 }
 
 .handle-label {
-	margin-left: 20px;
+	margin-left: 10px;
   display: inline-block;
   text-align: right;
 }

BIN
src/renderer/assets/image/a-biansu.png


BIN
src/renderer/assets/image/a-daoxu.png


BIN
src/renderer/assets/image/a-feige.png


BIN
src/renderer/assets/image/a-geshi.png


BIN
src/renderer/assets/image/a-hebing.png


BIN
src/renderer/assets/image/a-tiqu.png


BIN
src/renderer/assets/image/a-yasuo.png


BIN
src/renderer/assets/image/a-yinliang.png


+ 1 - 1
src/renderer/components/header.vue

@@ -77,7 +77,7 @@
 				</div>
 				<div class="font-12" style="padding: 20px; margin-bottom: 10px;">
 					<div style="text-align: center; margin-bottom: 10px;">
-						<p style="font-size: 16px;font-weight: 600;color: #f73131;">试用时限制文件大小为500KB</p>
+						<p style="font-size: 16px;font-weight: 600;color: #f73131;">非VIP限制文件大小为500KB</p>
 						<p style="font-size: 14px; font-weight: 600; margin-top: 15px;">开通会员即享以下权益</p>
 					</div>
 					<el-row :gutter="20" class="micon-list">

+ 423 - 52
src/renderer/components/home.vue

@@ -56,7 +56,10 @@
 								</div>
 							</el-col>
 							<el-col :span="6">
-								
+								<div class="citem-nav" @click="menuIndex = '8'">
+									<img src="../assets/image/a-tiqu.png" class="citem-img" />
+									<p class="citem-name">音频提取</p>
+								</div>
 							</el-col>
 						</el-row>
 					</div>
@@ -87,20 +90,41 @@
 									<el-tab-pane label="音频变速" name="5"></el-tab-pane>
 									<el-tab-pane label="音量调整" name="6"></el-tab-pane>
 									<el-tab-pane label="倒序播放" name="7"></el-tab-pane>
+									<el-tab-pane label="音频提取" name="8"></el-tab-pane>
 								</el-tabs>
 							</el-col>
 						</el-row>
 						
 					</div>
 					
-					<div v-if="audioList.length == 0" class="upload-area">
+					<div v-if="(menuIndex != '8' && audioList.length == 0) || (menuIndex == 8 && videoList.length == 0)" class="upload-area">
 						<div class="file-area" @click="pickFile()" id="drag-audio" @dragover.prevent @drop="handleDrop">
 							<div class="file-area-pos">
-								<img src="../assets/image/upload.png" style="width: 220px;"/>
+								<!-- <img src="../assets/image/upload.png" style="width: 220px;"/> -->
+								<img v-if="menuIndex == '1'" src="../assets/image/a-geshi.png" class="upload-img"/>
+								<img v-if="menuIndex == '2'" src="../assets/image/a-hebing.png" class="upload-img"/>
+								<img v-if="menuIndex == '3'" src="../assets/image/a-yasuo.png" class="upload-img"/>
+								<img v-if="menuIndex == '4'" src="../assets/image/a-feige.png" class="upload-img"/>
+								<img v-if="menuIndex == '5'" src="../assets/image/a-biansu.png" class="upload-img"/>
+								<img v-if="menuIndex == '6'" src="../assets/image/a-yinliang.png" class="upload-img"/>
+								<img v-if="menuIndex == '7'" src="../assets/image/a-daoxu.png" class="upload-img"/>
+								<img v-if="menuIndex == '8'" src="../assets/image/a-tiqu.png" class="upload-img"/>
 								<p style="font-size: 16px;">点击添加文件或拖拽文件到此</p>
-								<p style="font-size: 12px; color: #999;margin-top:15px;">不支持音乐平台付费格式音频,支持以下格式:</p>
-								<p style="font-size: 12px; color: #999;">mp3/wav/ogg/flac/mp2/m4a/m4r/ac3/amr/wma/aiff/</p>
-								<p style="font-size: 12px; color: #999;">aifc/caf/aac/ape/mmf/wv/au/voc/3gpp/mka/mp4</p>
+								<template v-if="menuIndex != '8'">
+									<div style="font-size: 12px; color: #999;padding-top:15px;">
+										<p>音乐平台会员音频为加密格式不支持,支持以下格式:</p>
+										<p>mp3/wav/ogg/flac/mp2/m4a/m4r/ac3/amr/wma/aiff/</p>
+										<p>aifc/caf/aac/ape/mmf/wv/au/voc/3gpp/mka/mp4</p>
+									</div>
+								</template>
+								<template v-else>
+									<div style="font-size: 12px; color: #999;padding-top:15px;">
+										<p>提取音频支持以下非加密视频格式:</p>
+										<p>webm/f4v/ogv/3gp/avi/flv/mkv/mov/mp4/mgp/rmvb/</p>
+										<p>wmv/wtv/mpeg/rm/asf/m4v/m2v/ts/mts/</p>
+										<p>m2t/m2ts/dv/mxf/mpg/3gpp/aif/mod/m4s</p>
+									</div>
+								</template>
 							</div>
 						</div>
 					</div>
@@ -109,6 +133,7 @@
 						<div class="content-left">
 							<div class="table-scroll" @dragover.prevent @drop="handleDrop">
 								<vxe-table
+									v-show="menuIndex != '8'"
 									show-overflow
 									class="img-table"
 									max-height="100%"
@@ -118,8 +143,7 @@
 									:row-config="{isHover: true}"
 									:edit-config="{trigger: 'click', mode: 'cell'}"
 									:data="audioList"
-									:scroll-y="{enabled: true}"
-									@cell-click="selectTab">
+									:scroll-y="{enabled: true}">
 									<vxe-column field="name" :title="'文件名称'+'(' + audioList.length + ')'"></vxe-column>
 							
 									<vxe-column field="sort" title="排序" width="140" v-if="menuIndex == '2'">
@@ -143,9 +167,45 @@
 											<el-progress :text-inside="true" :stroke-width="20" :percentage="row.percent"></el-progress>
 										</template>
 									</vxe-column>
-									<vxe-column title="操作" width="80">
+									<vxe-column title="操作" width="90">
+										<template #default="{ row, rowIndex }">
+											<i class="el-icon-view cur-pointer" style="font-size: 20px; margin-right: 5px;" @click="showFile(rowIndex)"></i>
+											<i class="el-icon-delete cur-pointer" style="font-size: 20px;" @click="delFile(rowIndex)"></i>
+										</template>
+									</vxe-column>
+								</vxe-table>
+								
+								<vxe-table
+									v-show="menuIndex == '8'"
+									show-overflow
+									class="img-table"
+									max-height="100%"
+									empty-text="没有更多数据了!"
+									:loading="tabLoading"
+									:loading-config="{icon: 'vxe-icon-indicator roll', text: '音频加载中...'}"
+									:row-config="{isHover: true}"
+									:edit-config="{trigger: 'click', mode: 'cell'}"
+									:data="videoList"
+									:scroll-y="{enabled: true}">
+									<vxe-column field="name" :title="'文件名称'+'(' + videoList.length + ')'"></vxe-column>
+									<vxe-column field="size" title="大小" width="140">
+										<template #default="{ row }">
+											<span>{{$utils.handleSize(row.size)}}</span>
+										</template>
+									</vxe-column>
+									<vxe-column field="duration" title="时间" width="140">
+										<template #default="{ row }">
+											<span>{{formatSeconds(row.duration)}}</span>
+										</template>
+									</vxe-column>
+									<vxe-column field="progress" title="转换进度" width="200">
+										<template #default="{ row }">
+											<el-progress :text-inside="true" :stroke-width="20" :percentage="row.percent"></el-progress>
+										</template>
+									</vxe-column>
+									<vxe-column title="操作" width="90">
 										<template #default="{ row, rowIndex }">
-											<i class="el-icon-delete cur-pointer" @click="delFile(rowIndex)"></i>
+											<i class="el-icon-delete cur-pointer" style="font-size: 20px;" @click="delVideoFile(rowIndex)"></i>
 										</template>
 									</vxe-column>
 								</vxe-table>
@@ -154,7 +214,7 @@
 						</div>
 					</div>
 					<!-- 底部设置区域 -->
-					<div class="img-footer-area" v-if="audioList.length > 0">
+					<div class="img-footer-area" v-if="(menuIndex != '8' && audioList.length > 0) || (menuIndex == 8 && videoList.length > 0)">
 						<div class="footer-line-between">
 							<!-- 1格式转化 -->
 							<div class="handle-item" v-if="menuIndex == '1' || menuIndex == '2'">
@@ -170,6 +230,7 @@
 								</el-select>
 								<label class="handle-label">码率:</label>
 								<el-select v-model="handleData.quality" style="width:100px;" size="small">
+									<el-option value="1" label="同源音频"></el-option>
 									<el-option value="8k" label="8 kbps"></el-option>
 									<el-option value="16k" label="16 kbps"></el-option>
 									<el-option value="24k" label="24 kbps"></el-option>
@@ -220,7 +281,7 @@
 								<label class="handle-label">分割模式:</label>
 								<el-select v-model="handleData.split_type" style="width:100px;" size="small">
 									<el-option :value="1" label="按份分割"></el-option>
-									<el-option :value="2" label="时长分割"></el-option>
+									<!-- <el-option :value="2" label="截取分割"></el-option> -->
 									<el-option :value="3" label="平均分割"></el-option>
 								</el-select>
 							
@@ -239,7 +300,8 @@
 									</el-select>
 								</template>
 								<template v-else>
-									<label class="handle-label">分割时间:</label>
+									<label v-if="handleData.split_type == 2" class="handle-label">截取时间:</label>
+									<label v-else class="handle-label">分割时间:</label>
 									<el-time-picker arrow-control @change="selectTime" v-model="split_timeStr" placeholder="选择时间" style="width:120px;" size="small"></el-time-picker>
 								</template>
 							</div>
@@ -265,6 +327,14 @@
 								</el-select>
 							</div>
 							
+							<!-- 提取音频 -->
+							<div class="handle-item" v-if="menuIndex == '8'">
+								<label class="handle-label">提取格式:</label>
+								<el-select v-model="videoFormat" style="width:100px;margin-left: 5px;" size="small">
+									<el-option v-for="(item, key) in outputVideo" :key="key" :value="item" :label="item"></el-option>
+								</el-select>
+							</div>
+							
 							<div v-else></div>
 							
 							<div>
@@ -273,19 +343,71 @@
 								<el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="打开保存目录">
 									<i class="el-icon-folder-opened" slot="reference" style="padding-left: 5px; cursor: pointer; font-size: 22px; vertical-align: middle;" @click="openFolder()"></i>
 								</el-popover>
-								<el-button type="danger" style="margin: 0 20px;" @click="exportFile()" :loading="loading">开始处理</el-button>
+								<el-button type="danger" style="margin-left: 20px;" @click="exportFile()" :loading="loading">开始处理</el-button>
 							</div>
 						</div>
 					</div>
 				</template>
-
+				
+				<!-- 文件信息弹窗 -->
+				<el-dialog title="文件详情" :visible.sync="fileDetailModel" width="500px">
+					<el-descriptions v-if="showIndex !== ''" class="margin-top"  :column="1" size="medium" border>
+					    <el-descriptions-item>
+							<template slot="label">
+								文件名
+							</template>
+							{{audioList[showIndex].name}}
+					    </el-descriptions-item>
+					    <el-descriptions-item>
+							<template slot="label">
+								比特率
+							</template>
+							{{audioList[showIndex].bitrate}}bps
+					    </el-descriptions-item>
+					    <el-descriptions-item>
+							<template slot="label">
+								时长
+							</template>
+							{{formatSeconds(audioList[showIndex].duration)}}
+					    </el-descriptions-item>
+					    <el-descriptions-item>
+							<template slot="label">
+								采样率
+							</template>
+							{{audioList[showIndex].sample_rate}}HZ
+					    </el-descriptions-item>
+						<el-descriptions-item>
+							<template slot="label">
+								歌手
+							</template>
+							{{audioList[showIndex].tags ? audioList[showIndex].tags.artist : '-'}}
+						</el-descriptions-item>
+						<el-descriptions-item>
+							<template slot="label">
+								标题
+							</template>
+							{{audioList[showIndex].tags ? audioList[showIndex].tags.title : '-'}}
+						</el-descriptions-item>
+						<el-descriptions-item>
+							<template slot="label">
+								唱片辑
+							</template>
+							{{audioList[showIndex].tags ? audioList[showIndex].tags.album : '-'}}
+						</el-descriptions-item>
+					    <el-descriptions-item>
+							<template slot="label">
+								其他
+							</template>
+							{{audioList[showIndex].tags ? audioList[showIndex].tags.encoder : '-'}}
+					    </el-descriptions-item>
+					  </el-descriptions>
+				</el-dialog>
 			</el-main>
 			<el-footer height="48px">
 				<!-- 更新 -->
 				<soft-update ref="updateRef" :showDowload="dowloadModel"
 					:dowloadFinish="finishModel"></soft-update>
 			</el-footer>
-		
 
 		</el-container>
 	</div>
@@ -314,6 +436,7 @@ export default {
 	},
 	data() {
 		return {
+			fileDetailModel: false,
 			//
 			loading: false,
 			tabLoading: false,
@@ -324,12 +447,17 @@ export default {
 			imgUrl: this.$api.imgUrl,
 			imgSrc: '',
 			audioList: [],
+			videoList: [],
 			imgInfo: '',
 			menuIndex: '', // 选中菜单
 
 			inputAudio: ['mp3', 'wav', 'ogg', 'flac', 'mp2', 'm4a', 'm4r', 'ac3', 'amr', 'wma', 'aiff','aifc','caf','aac','ape','mmf','wv','au','voc','3gpp','mka','mp4'],
 			outputAudio: ['mp3', 'wav', 'ogg', 'flac', 'mp2', 'm4a', 'm4r', 'ac3', 'amr', 'wma', 'aiff','aifc','caf','aac','ape','mmf','wv','au','voc','3gpp','mka','mp4'],
-
+			
+			inputVideo: ['video/x-msvideo', 'video/webm', 'video/f4v', 'video/ogv', 'video/3gp', 'video/avi', 'video/flv', 'video/mkv', 'video/mov', 'video/mp4', 'video/mgp', 'video/rmvb', 'video/wmv', 'video/wtv', 'video/mpeg', 'video/rm', 'video/asf', 'video/m4v', 'video/m2v', 'video/ts', 'video/mts', 'video/m2t', 'video/m2ts', 'video/dv', 'video/mxf', 'video/mpg', 'video/3gpp', 'video/aif', 'video/mod', 'video/m4s'],
+			outputVideo: ['mp3', 'wav', 'aac'],
+			videoFormat: 'mp3',
+			
 			downloadDir: '', // 默认下载目录
 			handleData: {
 				pathType: 2,
@@ -337,7 +465,7 @@ export default {
 				format: 'mp3',
 				newPath: os.userInfo().homedir + separator + "Downloads", // 新路径
 				type: 1, // 声道
-				quality: '128k', // 图片品质
+				quality: '1', // 图片品质
 				compressLevel: 1,
 				split_type: 1,
 				split_num: 2,
@@ -356,6 +484,7 @@ export default {
 
 			loadingTips: '',
 			execLimit: 5,
+			showIndex: '',
 		};
 	},
 	mounted() {
@@ -403,7 +532,12 @@ export default {
 			for(let i = 0; i < files.length; i++){
 				pathArr.push(files[i].path);
 			}
-			this.pushFileToList(pathArr);
+			if(this.menuIndex != '8'){
+				this.pushFileToList(pathArr);
+			}else{
+				this.pushFileToList2(pathArr);
+			}
+			
 		},
 		openVip() {
 			this.$refs.headerRef.openVip();
@@ -435,13 +569,15 @@ export default {
 		// 清除列表
 		clearList() {
 			this.audioList = [];
+			this.videoList = [];
+			this.showIndex = '';
 			this.handleData = {
 				pathType: 2,
 				isOriginal: true,
 				format: 'mp3',
 				newPath: os.userInfo().homedir + separator + "Downloads", // 新路径
 				type: 2, // 
-				quality: '128k', // 
+				quality: '1', // 
 				compressLevel: 1,
 				split_type: 1,
 				split_num: 2,
@@ -450,18 +586,29 @@ export default {
 		},
 		async pickFile(){
 			let formatArr = [];
-			this.inputAudio.map(item => {
-				formatArr.push(item.substr(item.lastIndexOf('/')+1))
-			})
+			if(this.menuIndex != '8'){
+				this.inputAudio.map(item => {
+					formatArr.push(item.substr(item.lastIndexOf('/')+1))
+				})
+			}else{
+				this.inputVideo.map(item => {
+					formatArr.push(item.substr(item.lastIndexOf('/')+1))
+				})
+			}
 			const spinLoad = this.$loading();
 			await electronApi.call('pickFile', [formatArr.join(','),true]).then(async(files) =>{
 				if(files.length > 0){
-					this.pushFileToList(files);
+					if(this.menuIndex != '8'){
+						this.pushFileToList(files);
+					}else{
+						this.pushFileToList2(files);
+					}
 				}
 				spinLoad.close();
 			}).catch(err => {
 				spinLoad.close();
 			});
+			
 		},
 		async pickDir(){
 			const spinLoad = this.$loading();
@@ -481,7 +628,11 @@ export default {
 				var stat = fs.statSync(filePath);
 
 				if (stat.isFile()) {
-					this.pushFileToList([filePath]);
+					if(this.menuIndex != '8'){
+						this.pushFileToList([filePath]);
+					}else{
+						this.pushFileToList2([filePath]);
+					}
 				} else if (stat.isDirectory()) {
 					this.dealDir(filePath)
 				}
@@ -551,11 +702,6 @@ export default {
 							this.audioList[index].channel = result.streams[0]['channels'];
 							this.audioList[index].sample_rate = result.streams[0]['sample_rate'];
 							this.audioList[index].tags = result.format.tags;
-									
-							// 设置第一个为默认信息
-							if(i == 0){
-								this.selectTab('',0);
-							}
 							
 							if(index == this.audioList.length - 1){
 								this.tabLoading = false;
@@ -576,6 +722,120 @@ export default {
 				this.tabLoading = false;
 			}, 500)
 		},
+		pushFileToList2(files) {
+			this.tabLoading = true;
+			for (let i = 0; i < files.length; i++) {
+				let path = files[i];
+				let filename = path.substr(path.lastIndexOf(separator)+1);
+				let suffix = filename.lastIndexOf('.') == -1 ? '' : filename.substr(filename.lastIndexOf('.')+1);
+				let size = fs.statSync(path).size;
+				let index = i;
+		
+				if (this.inputVideo.indexOf('video/'+suffix.toLowerCase()) == -1) {
+					this.$message({message: '不是有效的视频文件或该文件暂不支持!' + suffix , type: 'warning'});
+					continue;
+				} else {
+					if(!this.$refs.headerRef.authority.isAuthority){
+						if(size > 1024*500){
+							this.$notify.error({
+								title: '错误提示',
+								message: '免费版,文件最大不能超过500KB!'
+							});
+							continue;
+						}
+					}
+					
+					let imgInfo = {
+						name: filename,
+						size: Number(size),
+						path: path,
+						type: suffix,
+						duration: 0,
+						bitrate: '',
+						fenbianlv: '',
+						suffix: suffix,
+						percent: 0,
+						brand: '',
+					};
+					
+					let flag = true;
+					for (let m = 0; m < this.videoList.length; m++) {
+						if (this.videoList[m].name == imgInfo.name && this.videoList[m].path == imgInfo.path) {
+							flag = false;
+						}
+					}
+					
+					if (flag) {
+						this.videoList.push(imgInfo);
+						index = this.videoList.length - 1;
+					}else{
+						setTimeout(() => {
+							this.$message({message: '该文件已经在队列中 - ' + path, type: 'warning'});
+						}, 1000)
+						continue;
+					}
+					
+					setTimeout(() => {
+						electronApi.spawnExec(['ffprobe.exe','-i', path,'-v','quiet','-print_format','json','-show_format', '-show_streams', '-hide_banner']).then((result) => {
+							result = result.stdout.toString();
+							result = JSON.parse(result);
+							// 帧率
+							this.videoList[index].r_frame_rate = result.streams[0].r_frame_rate;
+							this.videoList[index].duration = result.format.duration;
+							this.videoList[index].bitrate = result.format.bit_rate;
+							
+							let type = filename.substr(filename.lastIndexOf('.')+1);
+							let brand = "";
+							let audioBitrate = "";
+							let fenbianlv = "";
+							let rotate = 0;
+							let v_codec_name = '';
+							let a_codec_name = '';
+							result.streams[1] = result.streams[1] ? result.streams[1] : {};
+							
+							if(result.format.tags && result.format.tags.compatible_brands){
+								brand = result.format.tags.compatible_brands;
+							}
+							if(result.streams[1] && result.streams[1].bit_rate){
+								audioBitrate = result.streams[1].bit_rate;
+							}
+							if(result.streams && result.streams[0]){
+								if(type.toLowerCase() == 'mpg' || type.toLowerCase() == 'vob'){
+									if(result.streams[1].width || result.streams[1].height){
+										fenbianlv = result.streams[1].width + 'x'+ result.streams[1].height;
+									}
+									v_codec_name = result.streams[1].codec_name;
+									a_codec_name = result.streams[2].codec_name;
+								}else{
+									if(result.streams[0].width || result.streams[0].height){
+										fenbianlv = result.streams[0].width + 'x'+ result.streams[0].height;
+									}
+									v_codec_name = result.streams[0].codec_name;
+									a_codec_name = result.streams[1].codec_name;
+								}
+															
+								if(result.streams[0].tags){
+									rotate = result.streams[0].tags.rotate;
+								}
+							}
+							this.videoList[index].fenbianlv = fenbianlv;
+							this.videoList[index].brand = brand;
+							this.videoList[index].audioBitrate = audioBitrate;
+							this.videoList[index].rotate = rotate;
+							this.videoList[index].v_codec_name = v_codec_name;
+							this.videoList[index].a_codec_name = a_codec_name;
+						});
+						
+						if(index == this.videoList.length - 1){
+							this.tabLoading = false;
+						}
+					}, 200)
+				}
+			}
+			setTimeout(()=>{
+				this.tabLoading = false;
+			}, 500)
+		},
 		// 音频时间转为秒
 		getSs(rawDuration){
 			const $ar = rawDuration.split(":");
@@ -597,7 +857,7 @@ export default {
 		// 导出
 		async exportFile(flag) {
 			let authority = this.$refs.headerRef.authority;
-			if (this.audioList.length > 0) {
+			if ((this.audioList.length > 0 && this.menuIndex != '8') || (this.videoList.length > 0 && this.menuIndex == '8')) {
 				if (!authority.isAuthority && !flag) {
 					this.$refs.headerRef.memberModel = true;
 					this.$refs.headerRef.isClick = true;
@@ -610,7 +870,7 @@ export default {
 					}, 3000)
 				}
 				
-				if(this.handleData.pathType == '2'){ // 自定义文件架判断有无 优速音频处理器 文件夹
+				if(this.handleData.pathType == '2'){ // 自定义文件架判断有无 音频处理器 文件夹
 					if(fs.existsSync(this.downloadDir + separator +  pjson.softInfo.softName)){
 						this.handleData.newPath = this.downloadDir + separator +  pjson.softInfo.softName;
 					} else {
@@ -621,21 +881,40 @@ export default {
 
 				let taskArr = [];
 				if(this.menuIndex != '2'){
-					for(let i=0; i< this.audioList.length; i++){
-						// 处理音频
-						let task = this.dealVideo(i, this.audioList[i]);
-						if(task){
-							taskArr.push(task);
+					if(this.menuIndex == '8'){
+						for(let i=0; i< this.videoList.length; i++){
+							// 处理音频
+							let task = this.dealVideo(i, this.videoList[i]);
+							if(task){
+								taskArr.push(task);
+							}
+							
+							if((i+1) % this.execLimit == 0){
+								await Promise.all(taskArr).then(result => {
+									taskArr = [];
+								}).catch(err => {
+									this.$message.error('部分音频操作错误,请调整参数后再试!');
+								})
+							}
 						}
-						
-						if((i+1) % this.execLimit == 0){
-							await Promise.all(taskArr).then(result => {
-								taskArr = [];
-							}).catch(err => {
-								this.$message.error('部分音频操作错误,请调整参数后再试!');
-							})
+					}else{
+						for(let i=0; i< this.audioList.length; i++){
+							// 处理音频
+							let task = this.dealVideo(i, this.audioList[i]);
+							if(task){
+								taskArr.push(task);
+							}
+							
+							if((i+1) % this.execLimit == 0){
+								await Promise.all(taskArr).then(result => {
+									taskArr = [];
+								}).catch(err => {
+									this.$message.error('部分音频操作错误,请调整参数后再试!');
+								})
+							}
 						}
 					}
+					
 				}else{
 					await this.dealConcatVideo();
 				}
@@ -650,11 +929,17 @@ export default {
 				}
 
 				// 打开文件夹
-				if(this.audioList.length > 0){
+				if(this.audioList.length > 0 && this.menuIndex != '8'){
 					this.$message('恭喜你,任务已完成!');
 					let outPath = this.handleData.newPath + separator + this.audioList[0].name.slice(this.audioList[0].name.lastIndexOf('/')+1);
 					electronApi.call('showItemInfolder',[outPath])
 				}
+				// 打开文件夹
+				if(this.videoList.length > 0 && this.menuIndex == '8'){
+					this.$message('恭喜你,任务已完成!');
+					let outPath = this.handleData.newPath + separator + this.videoList[0].name.slice(this.videoList[0].name.lastIndexOf('/')+1);
+					electronApi.call('showItemInfolder',[outPath])
+				}
 			}
 		},
 		// 处理音频
@@ -664,6 +949,7 @@ export default {
 			const regexTime = /time=(.*?) bitrate/;
 			switch (this.menuIndex) {
 				case '1': // 格式转换
+				case '2': // 音频合并
 				case '7': // 音频倒放
 					task = new Promise((resolve,reject) =>{
 						let filePath = file.path;
@@ -673,12 +959,14 @@ export default {
 
 						if(this.menuIndex == '1'){
 							outPath = this.handleData.newPath + separator + file.name.slice(0, file.name.lastIndexOf('.')) + '.' + suffix;
-						}else {
+						}else if(this.menuIndex == '7'){
 							let ss = suffix;
 							if(this.handleData.isOriginal){
 								ss = suffix2;
 							}
 							outPath = this.handleData.newPath + separator + file.name.slice(0, file.name.lastIndexOf('.')) + '.' + ss;
+						}else{
+							outPath = os.tmpdir() + separator + file.name.slice(0, file.name.lastIndexOf('.')) + '.' + suffix;;	
 						}
 
 						let params = [];
@@ -714,8 +1002,13 @@ export default {
 							params.push('-vn');
 						}
 
-						params.push('-b:a')
-						params.push(this.handleData.quality)
+						if(this.handleData.quality != '1' && this.menuIndex != '7'){
+							params.push('-b:a')
+							params.push(this.handleData.quality)
+						}else{
+							params.push('-b:a')
+							params.push(file.bitrate / 1000 + 'k');
+						}
 						
 						if(this.menuIndex == '7'){
 							params.push('-af');
@@ -978,7 +1271,7 @@ export default {
 						let params = [
 							'-i',
 							filePath,
-							'-filter:a',
+							'-af',
 							'volume='+this.handleData.volume,
 							'-vn',
 							outPath,
@@ -1013,8 +1306,62 @@ export default {
 						})
 					})
 					break;
+				case '8': // 提取音频
+					task = new Promise((resolve,reject) =>{
+						let filePath = file.path;
+						let suffix = this.videoFormat;
+						let outPath = this.handleData.newPath + "\/" + file.name.slice(0, file.name.lastIndexOf('.')) + '.'+suffix;
+						
+						let str = 'copy';
+						if(suffix == 'mp3'){
+							str = 'libmp3lame';
+						}
+					
+						let params = [
+							'-i',
+							filePath,
+							'-vn',
+							'-acodec',
+							str,
+							outPath,
+							'-hide_banner',
+							'-y'
+						];
+					
+						electronApi.spawnExec(['ffmpeg.exe',...params],{
+							stderr:(data) =>{
+								let timeStr = regexTime.exec(data.toString());
+								if(timeStr && timeStr[1]){
+									file.percent = Math.ceil((this.getSs(timeStr[1])/file.duration).toFixed(2) * 100);
+									if(file.percent < 1){
+										file.percent = 1;
+									}
+									if(this.videoList[index]){ // 运行中的数据 删除后 防止重新添加
+										this.videoList.splice(index, 1, file);
+									}
+								}
+							}
+						}).then(res => {
+							file.percent = 100
+							if(this.videoList[index]){ // 运行中的数据 删除后 防止重新添加
+								this.videoList.splice(index, 1, file);
+							}
+							resolve(true);
+						}).catch(err =>{
+							if(this.videoList[index]){ // 运行中的数据 删除后 防止重新添加
+								file.percent = 0 // 失败则进度设置为0
+								this.videoList.splice(index, 1, file);
+							}
+							this.$notify.error({
+								title: '文件错误',
+								message: '可能参数有误,请稍后再试! '+ file.path,
+							});
+							reject(err);
+						})
+					})
+					break;
 			}
-
+				
 			return task;
 		},
 		// 处理音频合成
@@ -1075,7 +1422,7 @@ export default {
 
 			let suffix = this.handleData.format;
 			let outPath = this.handleData.newPath + separator + '音频合并'+ this.formatNowDate() +'.'+suffix;
-			let filelist = os.tmpdir() + separator + 'yoso_audio.txt';
+			let filelist = os.tmpdir() + separator + 'xy_audio.txt';
 			let options = {mode: 438, flag: 'w'};
 			fs.writeFileSync(filelist,filePathArr.join("\n"),options);
 
@@ -1151,11 +1498,16 @@ export default {
 				})
 				this.isShow = false;
 			}).catch(err =>{
-				console.log('合并 ==',err);
+				console.log('合并 ==',err.stderr.toString());
 				this.isShow = false;
 				this.$message.error('操作失败,请重试!');
 			})
 		},
+		// 查看文件信息
+		showFile(rowIndex){
+			this.showIndex = rowIndex;
+			this.fileDetailModel = true;
+		},
 		// 删除文件
 		delFile(rowIndex){
 			this.$confirm('确认删除此音频吗?', '提示', {
@@ -1171,6 +1523,21 @@ export default {
 					  
 			});
 		},
+		// 删除文件
+		delVideoFile(rowIndex){
+			this.$confirm('确认删除此视频吗?', '提示', {
+				confirmButtonText: '确定',
+				cancelButtonText: '取消',
+				type: 'warning'
+			}).then(() => {
+				this.videoList.splice(rowIndex, 1);
+				if (this.videoList.length == 0) {
+					this.clearList();
+				}
+			}).catch(() => {
+					  
+			});
+		},
 		//文件排序
 		fileSort(type, index){
 			this.audioList.map((item, index) => {
@@ -1350,4 +1717,8 @@ export default {
 	.sort-btn{
 		padding: 7px !important;
 	}
+	
+	.upload-img{
+		width: 220px;
+	}
 </style>