Qwen3-ASR-0.6B Streamlit界面定制教程:添加时间戳对齐+导出SRT字幕功能
1. 引言:为什么需要字幕导出功能
如果你用过语音转文字工具,可能会遇到这样的困扰:转写出来的文字没有时间信息,想要制作视频字幕还得手动对齐时间轴,费时又费力。
今天我要分享的是如何为Qwen3-ASR-0.6B语音识别工具添加两个超级实用的功能:时间戳对齐和SRT字幕导出。这两个功能能让你的语音转文字结果直接变成可用的字幕文件,省去手动对齐的麻烦。
Qwen3-ASR-0.6B本身是个很棒的本地语音识别工具,支持中英文混合识别,完全离线运行保护隐私。但原版缺少时间戳功能,我们通过一些简单的代码改造,就能让它输出带时间信息的文字结果,并生成标准的SRT字幕格式。
2. 环境准备与基础代码
2.1 确保基础环境
在开始添加新功能前,你需要先确保基础环境正常工作。如果你还没有安装Qwen3-ASR,可以通过以下命令快速搭建:
# 创建项目目录 mkdir qwen3-asr-enhanced cd qwen3-asr-enhanced # 安装核心依赖 pip install torch torchaudio transformers streamlit2.2 获取基础代码
如果你已经有Qwen3-ASR的基础代码,可以直接在现有代码上修改。如果没有,这里是一个简化的基础框架:
import streamlit as st import torch from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor import librosa import tempfile import os # 初始化模型 @st.cache_resource def load_model(): model = AutoModelForSpeechSeq2Seq.from_pretrained( "Qwen/Qwen3-ASR-0.6B", torch_dtype=torch.float16, device_map="auto" ) processor = AutoProcessor.from_pretrained("Qwen/Qwen3-ASR-0.6B") return model, processor # 音频处理函数 def process_audio(audio_path): # 加载音频文件 audio, sr = librosa.load(audio_path, sr=16000) return audio, sr3. 添加时间戳对齐功能
3.1 理解时间戳原理
时间戳对齐的核心原理是让模型在输出文字的同时,也输出每个词或短语对应的时间位置。Qwen3-ASR模型本身支持返回时间戳信息,我们只需要在调用时开启相应参数。
3.2 修改识别函数
我们需要修改音频处理函数,让它在转写文字的同时返回时间戳信息:
def transcribe_with_timestamps(model, processor, audio_array, sampling_rate): # 预处理音频 inputs = processor( audio_array, sampling_rate=sampling_rate, return_tensors="pt", padding=True ) # 将输入数据移动到GPU(如果可用) inputs = {k: v.to(model.device) for k, v in inputs.items()} # 执行识别,开启时间戳返回 with torch.no_grad(): outputs = model.generate( **inputs, return_timestamps=True, # 关键参数:开启时间戳 output_scores=True ) # 解码结果 result = processor.batch_decode( outputs, skip_special_tokens=True, output_offsets=True # 获取时间偏移量 ) return result[0]3.3 处理时间戳结果
模型返回的时间戳信息需要进一步处理,转换成更易用的格式:
def process_timestamps(transcription_result): chunks = [] # 提取每个片段的时间信息和文本 for chunk in transcription_result.chunks: chunk_data = { "text": chunk.text, "start": chunk.timestamp[0], # 开始时间(秒) "end": chunk.timestamp[1] # 结束时间(秒) } chunks.append(chunk_data) return chunks4. 实现SRT字幕导出功能
4.1 了解SRT格式
SRT是最常见的字幕格式,结构很简单:
序号 开始时间 --> 结束时间 字幕文本 (空行)例如:
1 00:00:01,000 --> 00:00:04,000 你好,欢迎观看这个视频 2 00:00:05,000 --> 00:00:08,000 这是第二行字幕4.2 创建SRT生成函数
我们需要编写一个函数,将带时间戳的文字转换成SRT格式:
def generate_srt_content(chunks): srt_content = "" for i, chunk in enumerate(chunks, 1): # 转换时间格式(秒 → 时:分:秒,毫秒) start_time = format_timestamp(chunk["start"]) end_time = format_timestamp(chunk["end"]) # 构建SRT段落 srt_content += f"{i}\n" srt_content += f"{start_time} --> {end_time}\n" srt_content += f"{chunk['text']}\n\n" return srt_content def format_timestamp(seconds): """将秒数转换为SRT时间格式""" hours = int(seconds // 3600) minutes = int((seconds % 3600) // 60) secs = int(seconds % 60) millis = int((seconds - int(seconds)) * 1000) return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"4.3 添加下载按钮
在Streamlit界面中添加SRT文件下载功能:
def add_download_button(srt_content, filename_prefix): if srt_content: # 提供下载按钮 st.download_button( label="📥 下载SRT字幕文件", data=srt_content, file_name=f"{filename_prefix}_subtitles.srt", mime="text/plain" )5. 整合到Streamlit界面
5.1 修改主界面逻辑
现在我们需要把新功能整合到主界面中:
def main(): st.title("🎙️ Qwen3-ASR-0.6B 语音识别 + 字幕生成") # 侧边栏信息 st.sidebar.header("ℹ️ 功能特点") st.sidebar.info(""" - 支持中英文混合语音识别 - 自动生成时间戳信息 - 导出SRT字幕格式 - 完全本地运行,保护隐私 """) # 文件上传 uploaded_file = st.file_uploader( "📂 上传音频文件 (WAV/MP3/M4A/OGG)", type=["wav", "mp3", "m4a", "ogg"] ) if uploaded_file is not None: # 保存临时文件 with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_file: tmp_file.write(uploaded_file.getvalue()) tmp_path = tmp_file.name # 显示音频播放器 st.audio(uploaded_file) # 识别按钮 if st.button("🎯 开始识别并生成字幕", type="primary"): with st.spinner("正在识别音频,请稍候..."): # 加载模型 model, processor = load_model() # 处理音频 audio_array, sampling_rate = process_audio(tmp_path) # 执行识别(带时间戳) result = transcribe_with_timestamps(model, processor, audio_array, sampling_rate) # 处理时间戳结果 chunks = process_timestamps(result) # 显示识别结果 st.subheader("📊 识别结果(带时间戳)") for chunk in chunks: st.write(f"[{format_timestamp(chunk['start'])}] {chunk['text']}") # 生成并下载SRT st.subheader("🎬 SRT字幕文件") srt_content = generate_srt_content(chunks) add_download_button(srt_content, uploaded_file.name.split('.')[0]) # 清理临时文件 os.unlink(tmp_path) if __name__ == "__main__": main()5.2 优化用户体验
为了让界面更加友好,我们可以添加一些优化:
# 在文件上传后添加格式检查 def check_audio_file(file): if file is not None: if file.type not in ["audio/wav", "audio/mp3", "audio/m4a", "audio/ogg"]: st.error("不支持的音频格式,请上传WAV、MP3、M4A或OGG文件") return False return True # 添加进度提示 def show_progress(message): progress_bar = st.progress(0) status_text = st.empty() for i in range(100): progress_bar.progress(i + 1) status_text.text(f"{message}... {i+1}%") time.sleep(0.01) # 模拟进度 progress_bar.empty() status_text.empty()6. 完整代码示例
以下是整合所有功能的完整代码示例:
import streamlit as st import torch from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor import librosa import tempfile import os import time # 初始化模型 @st.cache_resource def load_model(): model = AutoModelForSpeechSeq2Seq.from_pretrained( "Qwen/Qwen3-ASR-0.6B", torch_dtype=torch.float16, device_map="auto" ) processor = AutoProcessor.from_pretrained("Qwen/Qwen3-ASR-0.6B") return model, processor # 音频处理 def process_audio(audio_path): audio, sr = librosa.load(audio_path, sr=16000) return audio, sr # 带时间戳的识别 def transcribe_with_timestamps(model, processor, audio_array, sampling_rate): inputs = processor( audio_array, sampling_rate=sampling_rate, return_tensors="pt", padding=True ) inputs = {k: v.to(model.device) for k, v in inputs.items()} with torch.no_grad(): outputs = model.generate( **inputs, return_timestamps=True, output_scores=True ) result = processor.batch_decode( outputs, skip_special_tokens=True, output_offsets=True ) return result[0] # 时间戳处理 def process_timestamps(transcription_result): chunks = [] for chunk in transcription_result.chunks: chunk_data = { "text": chunk.text, "start": chunk.timestamp[0], "end": chunk.timestamp[1] } chunks.append(chunk_data) return chunks # 时间格式转换 def format_timestamp(seconds): hours = int(seconds // 3600) minutes = int((seconds % 3600) // 60) secs = int(seconds % 60) millis = int((seconds - int(seconds)) * 1000) return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}" # 生成SRT内容 def generate_srt_content(chunks): srt_content = "" for i, chunk in enumerate(chunks, 1): start_time = format_timestamp(chunk["start"]) end_time = format_timestamp(chunk["end"]) srt_content += f"{i}\n{start_time} --> {end_time}\n{chunk['text']}\n\n" return srt_content # 主界面 def main(): st.set_page_config(page_title="语音识别字幕工具", layout="wide") st.title("🎙️ Qwen3-ASR-0.6B 语音识别 + 字幕生成") st.sidebar.header("ℹ️ 功能特点") st.sidebar.info("支持中英文混合识别,自动生成时间戳,导出SRT字幕") uploaded_file = st.file_uploader( "📂 上传音频文件", type=["wav", "mp3", "m4a", "ogg"] ) if uploaded_file: st.audio(uploaded_file) if st.button("🎯 开始识别并生成字幕", type="primary"): with st.spinner("识别中..."): with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_file: tmp_file.write(uploaded_file.getvalue()) tmp_path = tmp_file.name try: model, processor = load_model() audio_array, sampling_rate = process_audio(tmp_path) result = transcribe_with_timestamps(model, processor, audio_array, sampling_rate) chunks = process_timestamps(result) st.subheader("📊 识别结果") for chunk in chunks: st.write(f"[{format_timestamp(chunk['start'])}] {chunk['text']}") st.subheader("🎬 SRT字幕文件") srt_content = generate_srt_content(chunks) st.download_button( "📥 下载字幕", srt_content, f"{uploaded_file.name.split('.')[0]}.srt", "text/plain" ) finally: os.unlink(tmp_path) if __name__ == "__main__": main()7. 总结与进阶建议
通过本教程,你已经成功为Qwen3-ASR-0.6B语音识别工具添加了时间戳对齐和SRT字幕导出功能。现在你的工具不仅能转写文字,还能生成可直接用于视频编辑的字幕文件。
使用建议:
- 对于较长的音频,识别时间可能会稍长,请耐心等待
- 确保音频质量清晰,背景噪音会影响识别准确度
- 生成的SRT文件可以直接导入到Premiere、Final Cut Pro等视频编辑软件中
进阶改进方向:
- 添加批量处理功能,一次处理多个音频文件
- 支持更多字幕格式,如VTT、ASS等
- 添加字幕编辑功能,允许手动调整时间轴和文本
- 集成翻译功能,生成多语言字幕
现在你可以用这个增强版的语音识别工具,快速为你的视频内容生成准确的字幕,大大提高内容制作效率。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。