This commit is contained in:
@@ -314,7 +314,8 @@ def project_detail_api(request, project_id):
|
|||||||
ai_data = {
|
ai_data = {
|
||||||
'transcription': latest_task.transcription,
|
'transcription': latest_task.transcription,
|
||||||
'summary': latest_task.summary,
|
'summary': latest_task.summary,
|
||||||
'auto_chapters_data': latest_task.auto_chapters_data
|
'auto_chapters_data': latest_task.auto_chapters_data,
|
||||||
|
'transcription_data': latest_task.transcription_data
|
||||||
}
|
}
|
||||||
|
|
||||||
latest_task_any = TranscriptionTask.objects.filter(project=project).order_by('-created_at').first()
|
latest_task_any = TranscriptionTask.objects.filter(project=project).order_by('-created_at').first()
|
||||||
|
|||||||
@@ -108,9 +108,12 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h4 class="text-lg font-semibold text-gray-900 mb-3 flex items-center"><i class="fas fa-headphones mr-2 text-blue-500"></i>项目录音</h4>
|
<h4 class="text-lg font-semibold text-gray-900 mb-3 flex items-center"><i class="fas fa-headphones mr-2 text-blue-500"></i>项目录音</h4>
|
||||||
<div id="modalAudioSection" class="bg-gray-50 p-4 rounded-lg border border-gray-100 flex items-center justify-center min-h-[80px]">
|
<div id="modalAudioSection" class="bg-gray-50 p-4 rounded-t-lg border border-gray-100 flex items-center justify-center min-h-[80px]">
|
||||||
<!-- Audio player or "No audio" message will be injected here -->
|
<!-- Audio player or "No audio" message will be injected here -->
|
||||||
</div>
|
</div>
|
||||||
|
<div id="subtitleContainer" class="bg-black text-white p-3 rounded-b-lg text-center min-h-[48px] flex items-center justify-center text-lg font-medium" style="display: none;">
|
||||||
|
<span id="subtitleText"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="aiResultSection" style="display:none;" class="border border-indigo-100 rounded-xl overflow-hidden">
|
<div id="aiResultSection" style="display:none;" class="border border-indigo-100 rounded-xl overflow-hidden">
|
||||||
@@ -379,9 +382,17 @@ async function viewProject(id) {
|
|||||||
|
|
||||||
// Render Audio Player
|
// Render Audio Player
|
||||||
const audioSection = document.getElementById('modalAudioSection');
|
const audioSection = document.getElementById('modalAudioSection');
|
||||||
|
const subtitleContainer = document.getElementById('subtitleContainer');
|
||||||
|
const subtitleText = document.getElementById('subtitleText');
|
||||||
|
|
||||||
|
if (subtitleContainer && subtitleText) {
|
||||||
|
subtitleText.innerText = '';
|
||||||
|
subtitleContainer.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
if (data.audio_url) {
|
if (data.audio_url) {
|
||||||
audioSection.innerHTML = `
|
audioSection.innerHTML = `
|
||||||
<audio controls class="w-full">
|
<audio id="projectAudio" controls class="w-full">
|
||||||
<source src="${data.audio_url}" type="audio/mpeg">
|
<source src="${data.audio_url}" type="audio/mpeg">
|
||||||
<source src="${data.audio_url}" type="audio/mp4">
|
<source src="${data.audio_url}" type="audio/mp4">
|
||||||
您的浏览器不支持音频播放。
|
您的浏览器不支持音频播放。
|
||||||
@@ -403,6 +414,56 @@ async function viewProject(id) {
|
|||||||
if (data.ai_result) {
|
if (data.ai_result) {
|
||||||
aiSection.style.display = 'block';
|
aiSection.style.display = 'block';
|
||||||
|
|
||||||
|
// Subtitle integration
|
||||||
|
if (data.audio_url && data.ai_result.transcription_data && subtitleContainer && subtitleText) {
|
||||||
|
let transData = data.ai_result.transcription_data;
|
||||||
|
if (typeof transData === 'string') {
|
||||||
|
try { transData = JSON.parse(transData); } catch(e) { console.error('Error parsing transcription_data', e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transData && transData.Transcription && transData.Transcription.Paragraphs) {
|
||||||
|
subtitleContainer.style.display = 'flex';
|
||||||
|
|
||||||
|
const sentences = [];
|
||||||
|
transData.Transcription.Paragraphs.forEach(p => {
|
||||||
|
if (p.Words && p.Words.length > 0) {
|
||||||
|
let currentSentenceId = null;
|
||||||
|
let currentSentence = { text: '', start: 0, end: 0 };
|
||||||
|
|
||||||
|
p.Words.forEach(w => {
|
||||||
|
if (w.SentenceId !== currentSentenceId) {
|
||||||
|
if (currentSentenceId !== null) {
|
||||||
|
sentences.push({...currentSentence});
|
||||||
|
}
|
||||||
|
currentSentenceId = w.SentenceId;
|
||||||
|
currentSentence = { text: w.Text, start: w.Start, end: w.End };
|
||||||
|
} else {
|
||||||
|
currentSentence.text += w.Text;
|
||||||
|
currentSentence.end = w.End;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (currentSentenceId !== null) {
|
||||||
|
sentences.push({...currentSentence});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const audio = document.getElementById('projectAudio');
|
||||||
|
if (audio) {
|
||||||
|
audio.addEventListener('timeupdate', () => {
|
||||||
|
const currentTimeMs = audio.currentTime * 1000;
|
||||||
|
// Add a small buffer (e.g. 200ms) to make subtitle display smoother
|
||||||
|
const activeSentence = sentences.find(s => currentTimeMs >= (s.start - 200) && currentTimeMs <= (s.end + 200));
|
||||||
|
if (activeSentence) {
|
||||||
|
subtitleText.innerText = activeSentence.text;
|
||||||
|
} else {
|
||||||
|
subtitleText.innerText = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const summaryDiv = document.getElementById('modalAiSummary');
|
const summaryDiv = document.getElementById('modalAiSummary');
|
||||||
const toggleBtn = document.getElementById('toggleAiSummaryBtn');
|
const toggleBtn = document.getElementById('toggleAiSummaryBtn');
|
||||||
const toggleText = document.getElementById('toggleAiSummaryText');
|
const toggleText = document.getElementById('toggleAiSummaryText');
|
||||||
|
|||||||
Reference in New Issue
Block a user