'commit'
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
/.idea/
|
/.idea/
|
||||||
*.log
|
*.log
|
||||||
/Output/
|
/Output/
|
||||||
|
/DouYin/DownloadedVideos/
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
# 黄海在公司内网开发时的配置信息
|
# 黄海在公司内网开发时的配置信息
|
||||||
DORIS_HOST = "10.10.14.204"
|
# DORIS_HOST = "10.10.14.204"
|
||||||
DORIS_PORT = 9030
|
# DORIS_PORT = 9030
|
||||||
DORIS_FENODES = "10.10.14.204:8030"
|
# DORIS_FENODES = "10.10.14.204:8030"
|
||||||
REDIS_HOST = '10.10.14.14'
|
# REDIS_HOST = '10.10.14.14'
|
||||||
REDIS_PASSWORD = None # 如果没有密码则设为 None
|
# REDIS_PASSWORD = None # 如果没有密码则设为 None
|
||||||
|
|
||||||
# 黄海在家开发时的配置信息
|
# 黄海在家开发时的配置信息
|
||||||
# DORIS_HOST = "www.hzkjai.com"
|
DORIS_HOST = "www.hzkjai.com"
|
||||||
# DORIS_PORT = 27025
|
DORIS_PORT = 27025
|
||||||
# DORIS_FENODES = "www.hzkjai.com:27024"
|
DORIS_FENODES = "www.hzkjai.com:27024"
|
||||||
# REDIS_HOST = '127.0.0.1'
|
REDIS_HOST = '127.0.0.1'
|
||||||
# REDIS_PASSWORD = "DsideaL147258369"
|
REDIS_PASSWORD = "DsideaL147258369"
|
||||||
|
|
||||||
# 视觉模型配置
|
# 视觉模型配置
|
||||||
VL_MODEL_NAME = "qwen3-vl-flash"
|
VL_MODEL_NAME = "qwen3-vl-flash"
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,7 +3,6 @@ import os
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from dashscope import Files
|
|
||||||
|
|
||||||
# Ensure project root is in path
|
# Ensure project root is in path
|
||||||
sys.path.append(r"d:\dsWork\aiData")
|
sys.path.append(r"d:\dsWork\aiData")
|
||||||
@@ -32,104 +31,33 @@ async def transcribe_all():
|
|||||||
txt_path = os.path.join(transcript_dir, txt_filename)
|
txt_path = os.path.join(transcript_dir, txt_filename)
|
||||||
|
|
||||||
if os.path.exists(txt_path):
|
if os.path.exists(txt_path):
|
||||||
logger.info(f"Skipping (already exists): {txt_filename}")
|
# Check if file is empty
|
||||||
continue
|
if os.path.getsize(txt_path) > 0:
|
||||||
|
logger.info(f"Skipping (already exists): {txt_filename}")
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
logger.info(f"Re-processing empty file: {txt_filename}")
|
||||||
|
|
||||||
logger.info(f"Processing: {filename}")
|
logger.info(f"Processing: {filename}")
|
||||||
|
|
||||||
uploaded_file = None
|
|
||||||
try:
|
try:
|
||||||
# 1. Upload file to DashScope
|
# Direct local file transcription using Recognition API
|
||||||
logger.info(f"Uploading {filename} to DashScope...")
|
text = await client.transcribe_file(audio_path)
|
||||||
# Use purpose='assistants' to bypass jsonl check
|
|
||||||
upload_resp = Files.upload(audio_path, purpose='assistants', description=filename)
|
|
||||||
|
|
||||||
if upload_resp.status_code == 200:
|
if text:
|
||||||
# Handle output structure (dict or object)
|
with open(txt_path, 'w', encoding='utf-8') as f:
|
||||||
output_data = upload_resp.output
|
f.write(text)
|
||||||
uploaded_files = None
|
logger.info(f"Saved transcript to: {txt_filename}")
|
||||||
|
|
||||||
if hasattr(output_data, 'uploaded_files'):
|
|
||||||
uploaded_files = output_data.uploaded_files
|
|
||||||
elif isinstance(output_data, dict):
|
|
||||||
uploaded_files = output_data.get('uploaded_files')
|
|
||||||
|
|
||||||
if not uploaded_files:
|
|
||||||
logger.error(f"No uploaded_files in response: {output_data}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
uploaded_file = uploaded_files[0]
|
|
||||||
logger.info(f"Uploaded file info: {uploaded_file}")
|
|
||||||
|
|
||||||
# Handle uploaded_file structure
|
|
||||||
file_id = None
|
|
||||||
if hasattr(uploaded_file, 'file_id'):
|
|
||||||
file_id = uploaded_file.file_id
|
|
||||||
elif isinstance(uploaded_file, dict):
|
|
||||||
file_id = uploaded_file.get('file_id')
|
|
||||||
|
|
||||||
if not file_id:
|
|
||||||
logger.error(f"No file_id in uploaded file: {uploaded_file}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
logger.info(f"Uploaded successfully. File ID: {file_id}")
|
|
||||||
|
|
||||||
# Try passing file_id. If that fails, we might need another approach.
|
|
||||||
# According to some docs, file_urls=["file-xxx"] works.
|
|
||||||
target_url = file_id
|
|
||||||
else:
|
else:
|
||||||
logger.error(f"Upload failed: {upload_resp}")
|
logger.error(f"Failed to transcribe: {filename}")
|
||||||
continue
|
|
||||||
|
|
||||||
# 2. Transcribe
|
|
||||||
logger.info(f"Transcribing {file_id}...")
|
|
||||||
output = await client.transcribe_audio(file_urls=[target_url])
|
|
||||||
|
|
||||||
if output and output.task_status == 'SUCCEEDED':
|
|
||||||
# Parse results
|
|
||||||
results = output.results
|
|
||||||
if results:
|
|
||||||
for res in results:
|
|
||||||
transcription_url = res.get('transcription_url')
|
|
||||||
if transcription_url:
|
|
||||||
# Download result
|
|
||||||
trans_data = await client.download_transcription_result(transcription_url)
|
|
||||||
if trans_data:
|
|
||||||
# Extract text
|
|
||||||
# text_with_ts = await client.extract_transcript_with_timestamp(trans_data)
|
|
||||||
text_clean = await client.extract_transcript_without_timestamp(trans_data)
|
|
||||||
|
|
||||||
# Save to file
|
|
||||||
with open(txt_path, 'w', encoding='utf-8') as f:
|
|
||||||
f.write(text_clean)
|
|
||||||
logger.info(f"Saved transcript to: {txt_filename}")
|
|
||||||
else:
|
|
||||||
logger.error(f"Failed to download transcript for {filename}")
|
|
||||||
else:
|
|
||||||
logger.error(f"No transcription_url in result for {filename}")
|
|
||||||
else:
|
|
||||||
logger.error(f"No results in output for {filename}")
|
|
||||||
else:
|
|
||||||
logger.error(f"Transcription failed for {filename}")
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error processing {filename}: {e}")
|
logger.error(f"Error processing {filename}: {str(e)}", exc_info=True)
|
||||||
|
|
||||||
finally:
|
|
||||||
# 3. Cleanup: Delete uploaded file
|
|
||||||
if uploaded_file:
|
|
||||||
try:
|
|
||||||
fid = None
|
|
||||||
if hasattr(uploaded_file, 'file_id'):
|
|
||||||
fid = uploaded_file.file_id
|
|
||||||
elif isinstance(uploaded_file, dict):
|
|
||||||
fid = uploaded_file.get('file_id')
|
|
||||||
|
|
||||||
if fid:
|
|
||||||
Files.delete(fid)
|
|
||||||
logger.info(f"Deleted remote file {fid}")
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"Failed to delete remote file: {e}")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(transcribe_all())
|
try:
|
||||||
|
asyncio.run(transcribe_all())
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logger.info("Stopped by user")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Fatal error: {str(e)}", exc_info=True)
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ class ASRClient:
|
|||||||
logger.error(f"初始化ASR客户端失败: {str(e)}", exc_info=True)
|
logger.error(f"初始化ASR客户端失败: {str(e)}", exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
async def transcribe_file(self, file_path):
|
def transcribe_file_sync(self, file_path):
|
||||||
"""
|
"""
|
||||||
转写本地音频文件
|
转写本地音频文件 (同步版本)
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file_path: 本地音频文件路径
|
file_path: 本地音频文件路径
|
||||||
@@ -44,7 +44,7 @@ class ASRClient:
|
|||||||
Returns:
|
Returns:
|
||||||
str: 转写后的文本,如果失败返回None
|
str: 转写后的文本,如果失败返回None
|
||||||
"""
|
"""
|
||||||
logger.info(f"开始转写文件: {file_path}")
|
logger.info(f"开始转写文件(Sync): {file_path}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
recognition = Recognition(
|
recognition = Recognition(
|
||||||
@@ -54,9 +54,7 @@ class ASRClient:
|
|||||||
callback=None
|
callback=None
|
||||||
)
|
)
|
||||||
|
|
||||||
# Run blocking call in executor
|
result = recognition.call(file_path)
|
||||||
loop = asyncio.get_running_loop()
|
|
||||||
result = await loop.run_in_executor(None, lambda: recognition.call(file_path))
|
|
||||||
|
|
||||||
if result.status_code == HTTPStatus.OK:
|
if result.status_code == HTTPStatus.OK:
|
||||||
sentences = []
|
sentences = []
|
||||||
@@ -73,3 +71,16 @@ class ASRClient:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"转写过程出错: {str(e)}", exc_info=True)
|
logger.error(f"转写过程出错: {str(e)}", exc_info=True)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def transcribe_file(self, file_path):
|
||||||
|
"""
|
||||||
|
转写本地音频文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path: 本地音频文件路径
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: 转写后的文本,如果失败返回None
|
||||||
|
"""
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
return await loop.run_in_executor(None, self.transcribe_file_sync, file_path)
|
||||||
|
|||||||
Binary file not shown.
@@ -360,7 +360,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
// ================= 配置数据 =================
|
// ================= 配置数据 =================
|
||||||
const students = ["刘美希", "林子琪", "唐纯瑞", "林子皓", "刘若曦", "王艺诺", "邹泓凯", "王梓博", "肖靖泽", "彭馨瑶", "刘丰源", "黄琬乔", "赵敏智"];
|
const students = ["刘美希", "林子琪", "唐纯瑞", "林子皓", "刘若曦","冯筱壹", "王艺诺", "邹泓凯", "王梓博", "肖靖泽", "彭馨瑶", "刘丰源", "黄琬乔", "赵敏智"];
|
||||||
const colors = [
|
const colors = [
|
||||||
'#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8',
|
'#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8',
|
||||||
'#F7DC6F', '#BB8FCE', '#F1948A', '#82E0AA', '#D7BDE2',
|
'#F7DC6F', '#BB8FCE', '#F1948A', '#82E0AA', '#D7BDE2',
|
||||||
|
|||||||
Reference in New Issue
Block a user