Browse Source

init finish

liqiong 5 months ago
commit
795d8f2a87

+ 1 - 0
.qiniu_pythonsdk_hostscache.json

@@ -0,0 +1 @@
+{"http:DqyIKObe1EoV3S4U_Z_PY-P_G6zybg8Dj2xuDARL:temp": {"upHosts": ["http://upload-z2.qiniup.com", "http://up-z2.qiniup.com", "http://upload-cn-south-1.qiniuio.com"], "ioHosts": ["http://iovip-z2.qbox.me"], "rsHosts": ["http://rs-z2.qbox.me"], "rsfHosts": ["http://rsf-z2.qbox.me"], "apiHosts": ["http://api-z2.qiniu.com"], "deadline": 1734079037}, "http:RXXZaNASEzofDCv2ofOilJ4AujYyBa5GBEiiM1Wc:sc-op": {"upHosts": ["http://upload.qiniup.com", "http://up.qiniup.com", "http://upload-cn-east-1.qiniuio.com"], "ioHosts": ["http://iovip.qbox.me"], "rsHosts": ["http://rs-z0.qbox.me"], "rsfHosts": ["http://rsf-z0.qbox.me"], "apiHosts": ["http://api.qiniu.com"], "deadline": 1734079407}}

BIN
ffmpeg.exe


BIN
input/02.mp4


+ 6 - 0
input/mp4_2_mp3.bat

@@ -0,0 +1,6 @@
+@echo off
+for %%f in (*.mp4) do (
+    ffmpeg -i "%%f" -vn -acodec mp3 "%%~nf.mp3"
+)
+echo Conversion complete!
+pause

+ 44 - 0
query_subtitle.py

@@ -0,0 +1,44 @@
+import json
+import requests
+import sys
+
+
+
+def query(file_json_name,id):
+	url = "https://openspeech.bytedance.com/api/v1/auc/query"
+
+	data = {
+		"appid": "appid-9344610069",
+		"token": "token-jGlG-1bU93gdrnLUqOQd44Y474k4J3KC",
+		"cluster": "volc_auc_common",
+		"id": f"{id}"
+		}
+
+	headers = {
+		"Content-Type": "application/json",
+		"Authorization": "Authorization-Bearer;jGlG-1bU93gdrnLUqOQd44Y474k4J3KC"}
+
+	response = requests.post(url, json=data, headers=headers)
+
+	with open(f"subtitle/{file_json_name}","w") as f:
+		f.write(response.text)
+
+
+
+
+if __name__ == '__main__':
+
+	if len(sys.argv) > 1:
+		json_file_path = sys.argv[1]
+		with open(json_file_path,"r") as file:
+			data=json.loads(file.read())
+			for x in data:
+				file_json_name = x["fileName"].replace("mp3","json")
+				query(file_json_name,x["submitId"])
+				print(f"{file_json_name} save success!!!")
+	else:
+		print("没有传递参数!")
+
+	
+
+

+ 3 - 0
readme.md

@@ -0,0 +1,3 @@
+### 需要准备的材料
+
+

BIN
resource/luojigou.mp3


BIN
resource/xiaodou.mp3


BIN
resource/xiaodou001.mp3


BIN
resource/xiaodou002.mp3


+ 184 - 0
run.py

@@ -0,0 +1,184 @@
+import json
+import glob
+import string
+import unicodedata
+from datetime import datetime
+import os
+import subprocess
+import threading
+from concurrent.futures import ThreadPoolExecutor
+
+
+findText="琪琪"
+replace_audio_file_name="resource/xiaodou002.mp3"
+
+
+def count_all_punctuation(text):
+	chinese_punctuation = ",。!?《》【】、"
+	count = 0
+	for char in text:
+		if char in string.punctuation or char in chinese_punctuation or unicodedata.category(char).startswith('P'):
+			count += 1
+	return count
+
+
+# 线程池任务执行函数
+def execCMD(command):
+	print(command)
+	try:
+		# 执行命令并获取结果
+		result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
+		if result.returncode == 0:
+			print("命令执行成功!")
+		else:
+			print(f"命令执行失败: {result.stderr}")
+	except Exception as e:
+		print(f"执行命令时发生错误: {str(e)}")
+
+
+def mergeAudio(file_list_name):
+	output_mp3_name=file_list_name.replace(".txt",".mp3")
+	command=f"ffmpeg -f concat -safe 0 -i {file_list_name} -c -c:a libmp3lame -b:a 128k copy {output_mp3_name}"
+	print(command)
+	try:
+		# 执行命令并获取结果
+		result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
+		if result.returncode == 0:
+			print("音频合并成功!")
+		else:
+			print(f"音频合并执行失败: {result.stderr}")
+	except Exception as e:
+		print(f"执行命令时发生错误: {str(e)}")
+
+
+def mergeAudio002(audios,mergeAudioName):
+
+	# command=f'ffmpeg -i output/03_000000.mp3 -i resource/xiaodou002.mp3 -i output/03_000010.mp3 -i resource/xiaodou002.mp3 -filter_complex "[0][1][2][3]concat=n=4:v=0:a=1" -y merge/03_0000.mp3'
+	command=f'ffmpeg'
+	for audio in audios:
+		command+=" -i "+audio
+	command+=" -filter_complex "
+	command+='"'
+	for x in range(len(audios)):
+		command+=f"[{str(x)}]"
+	command+=f"concat=n={str(len(audios))}:v=0:a=1"
+	command+='"'
+	command+=f" -y {mergeAudioName}"
+
+	try:
+		# 执行命令并获取结果
+		result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
+		if result.returncode == 0:
+			print("音频合并成功!")
+		else:
+			print(f"音频合并执行失败: {result.stderr}")
+	except Exception as e:
+		print(f"执行命令时发生错误: {str(e)}")
+
+
+def merge_audio_video(video_file,audio_file,output_file):
+
+	command=f"ffmpeg -i {video_file} -i {audio_file} -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -strict experimental {output_file}"
+
+	try:
+		# 执行命令并获取结果
+		result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
+		if result.returncode == 0:
+			print("音频替换成功!")
+		else:
+			print(f"音频替换执行失败: {result.stderr}")
+	except Exception as e:
+		print(f"执行命令时发生错误: {str(e)}")
+
+
+def replace_audio(splits):
+
+	if len(splits)==1:
+		return [], None
+
+	file_name=os.path.basename(splits[0]['filePath']).replace(".mp3","")
+
+	audios=[]
+	for index,x in enumerate(splits):
+		if 'endTime' in x:
+			cmd=f"ffmpeg -i {x['filePath']} -ss {x['startTime']} -to {x['endTime']} -ac 2 -ar 44100 -ab 128k -y output/{file_name}0000{index}.mp3"
+			audios.append(f"output/{file_name}0000{index}.mp3")
+			audios.append(replace_audio_file_name)
+		else:
+			cmd=f"ffmpeg -i {x['filePath']} -ss {x['startTime']} -ac 2 -ar 44100 -ab 128k -y output/{file_name}0000{index}.mp3"
+			audios.append(f"output/{file_name}0000{index}.mp3")
+		execCMD(cmd)
+
+	return audios,file_name
+
+def timeConversion(time):
+	seconds = time // 1000
+	milliseconds_remaining = time % 1000
+	minutes = seconds // 60
+	seconds_remaining = seconds % 60
+	time_str = "{:02}:{:02}:{:02}.{:03}".format(minutes // 60, minutes % 60, seconds_remaining, milliseconds_remaining)
+	return time_str
+
+
+def exJson(path):
+	with open(path, 'r', encoding='utf-8') as file:
+		# print(os.path.dirname(path).replace("subtitle","input"))
+		splits=[]
+		times=[0]
+		file_path = os.path.dirname(path).replace("subtitle","input")+"/"+os.path.basename(path).replace("json","mp3")
+		content = file.read().strip()
+		jsonData = json.loads(content)
+		respData = jsonData["resp"]
+		for utterance in respData["utterances"]:
+			text=utterance["text"]
+			if findText in text:
+				findIndex=text.find(findText)
+				words=utterance["words"]
+				findIndex=findIndex-count_all_punctuation(text[:findIndex])
+				startIndex=findIndex
+				endIndex=findIndex+len(findText)
+
+				# print("startTime")
+				# print(words[startIndex]["start_time"])
+				# print(timeConversion(words[startIndex]["start_time"]))
+				# print("endTime")
+				# print(words[endIndex]["end_time"])
+				# print("--------------------------------")
+				times.append(words[startIndex]["start_time"])
+				times.append(words[endIndex]["end_time"])
+
+				# splits.append({'filePath':file_path,'startTime':timeConversion(words[startIndex]["start_time"]),'endTime':timeConversion(words[startIndex]["end_time"])})
+
+		# replace_audio(splits)
+
+		for i in range(0, len(times), 2):
+			if i+1==len(times):
+				splits.append({'filePath':file_path,'startTime':timeConversion(times[i])})
+			else:
+				splits.append({'filePath':file_path,'startTime':timeConversion(times[i]),'endTime':timeConversion(times[i+1])})
+
+
+		audios,file_name=replace_audio(splits)
+
+		if len(audios)==0:
+			return
+
+		mergeAudio002(audios,f"merge/{file_name}0000.mp3")
+
+		merge_audio_video(f"input/{file_name}.mp4",f"merge/{file_name}0000.mp3",f"output_video/{file_name}.mp4")
+
+
+if __name__ == '__main__':
+
+	for x in glob.glob(r"D:\replace_audio_script\merge\*"):
+		os.remove(x)
+
+	for x in glob.glob(r"D:\replace_audio_script\output\*"):
+		os.remove(x)
+
+	for x in glob.glob(r"D:\replace_audio_script\output_video\*"):
+		os.remove(x)
+
+	for x in glob.glob(r"D:\replace_audio_script\subtitle\*.json"):
+		exJson(x)
+

+ 0 - 0
submit_mp3.py


BIN
test/lll.mp3


BIN
test/luojigou.mp3


BIN
test/test_submit.mp3


+ 59 - 0
test/tts_http_demo.py

@@ -0,0 +1,59 @@
+#coding=utf-8
+
+'''
+requires Python 3.6 or later
+pip install requests
+'''
+import base64
+import json
+import uuid
+import requests
+
+# 填写平台申请的appid, access_token以及cluster
+appid = "4600087561"
+access_token= "ATXbVUCNRIzjZQs3ML3ev_fT53LDHiUD"
+cluster = "volcano_icl"
+
+voice_type = "S_toCOrDx61"
+host = "openspeech.bytedance.com"
+api_url = f"https://{host}/api/v1/tts"
+
+header = {"Authorization": f"Bearer;{access_token}"}
+
+request_json = {
+    "app": {
+        "appid": appid,
+        "token": "access_token",
+        "cluster": cluster
+    },
+    "user": {
+        "uid": "388808087185078"
+    },
+    "audio": {
+        "voice_type": voice_type,
+        "encoding": "mp3",
+        "speed_ratio": 1.0,
+        "volume_ratio": 1.0,
+        "pitch_ratio": 1.0,
+    },
+    "request": {
+        "reqid": str(uuid.uuid4()),
+        "text": "小朋友,看出来小逗是怎么整理的吗?",
+        "text_type": "plain",
+        "operation": "query",
+        "with_frontend": 1,
+        "frontend_type": "unitTson"
+
+    }
+}
+
+if __name__ == '__main__':
+    try:
+        resp = requests.post(api_url, json.dumps(request_json), headers=header)
+        print(f"resp body: \n{resp.json()}")
+        if "data" in resp.json():
+            data = resp.json()["data"]
+            file_to_save = open("test_submit.mp3", "wb")
+            file_to_save.write(base64.b64decode(data))
+    except Exception as e:
+        e.with_traceback()

+ 63 - 0
upload_and_submit.py

@@ -0,0 +1,63 @@
+import glob
+import hashlib
+import os
+
+from qiniu import Auth, put_file, etag
+import qiniu.config
+import time
+import json
+import requests
+
+
+q = Auth("RXXZaNASEzofDCv2ofOilJ4AujYyBa5GBEiiM1Wc","rOvRaTkUUnqHus8RXx2awqx2yZYR5Q3n37n4QC5A")
+bucket_name = 'sc-op'
+
+token = q.upload_token(bucket_name, None, 36000)
+
+
+def submit_subtitle(mp3url):
+
+	url = "https://openspeech.bytedance.com/api/v1/auc/submit"
+
+	data = {
+		"app": {
+			"appid": "appid344610069",
+			"token": "tokenGlG-1bU93gdrnLUqOQd44Y474k4J3KC",
+			"cluster": "volc_auc_common"
+		},
+		"user": {
+			"uid": "388808087185088"
+	   },
+		"audio": {
+			"format": "mp3",
+			"url": f"{mp3url}"
+		},
+		"additions": {
+			"use_itn": "False",
+			"with_speaker_info": "True"
+		}
+	}
+
+	headers = {
+		"Content-Type": "application/json",
+		"Authorization": "Authorization-Bearer;jGlG-1bU93gdrnLUqOQd44Y474k4J3KC"}
+
+	response = requests.post(url, json=data, headers=headers)
+
+	if response.status_code==200:
+		result_json=json.loads(response.text)
+		return result_json["resp"]["id"]
+
+
+if __name__ == '__main__':
+	readable_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
+	file_list=[]
+	with open(f"input/{readable_time}.txt","w") as f:
+		for x in glob.glob(r"input\02.mp3"):
+			print(x)
+			ret, info = put_file(token, None, x)
+			mp3url="https://sc.miaokids.com/"+ret['key']
+			subtitle_submit_id = submit_subtitle(mp3url)
+			jsonStr={"fileName":f"{os.path.basename(x)}","fileUrl":f"{mp3url}","submitId":subtitle_submit_id}
+			file_list.append(jsonStr)
+		f.write(json.dumps(file_list, ensure_ascii=False, indent=4))

BIN
思维课语音替换脚本需求说明.docx