diff --git a/lib/blocs/transcription/transcription_bloc.dart b/lib/blocs/transcription/transcription_bloc.dart index 7ebe141..f6d93f7 100644 --- a/lib/blocs/transcription/transcription_bloc.dart +++ b/lib/blocs/transcription/transcription_bloc.dart @@ -73,6 +73,16 @@ class TranscriptionBloc extends Bloc { final result = await _whisperService.transcribe( videoPath, // Pass video file directly language: event.language ?? 'auto', + onProgress: (progress) { + if (!emit.isDone) { + emit(Transcribing( + videoPath: videoPath, + fileName: fileName, + statusMessage: 'Transcribing...', + progress: progress, + )); + } + }, ); emit(TranscriptionComplete( diff --git a/lib/blocs/transcription/transcription_state.dart b/lib/blocs/transcription/transcription_state.dart index 56f5c57..c2a7d51 100644 --- a/lib/blocs/transcription/transcription_state.dart +++ b/lib/blocs/transcription/transcription_state.dart @@ -19,10 +19,7 @@ class VideoSelected extends TranscriptionState { final String videoPath; final String fileName; - const VideoSelected({ - required this.videoPath, - required this.fileName, - }); + const VideoSelected({required this.videoPath, required this.fileName}); @override List get props => [videoPath, fileName]; @@ -51,10 +48,7 @@ class AudioExtracting extends TranscriptionState { final String videoPath; final String fileName; - const AudioExtracting({ - required this.videoPath, - required this.fileName, - }); + const AudioExtracting({required this.videoPath, required this.fileName}); @override List get props => [videoPath, fileName]; @@ -65,15 +59,16 @@ class Transcribing extends TranscriptionState { final String videoPath; final String fileName; final String statusMessage; - + final int progress; const Transcribing({ required this.videoPath, required this.fileName, this.statusMessage = 'Transcribing...', + this.progress = 0, }); @override - List get props => [videoPath, fileName, statusMessage]; + List get props => [videoPath, fileName, statusMessage, progress]; } /// Transcription completed successfully. diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 15bd334..01d397f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -33,7 +33,8 @@ } }, "extractingAudio": "Extracting audio from video...", - "processingTranscription": "Whisper is processing...", + "processingTranscription": "Transcription in progress...", + "preprocessingStatus": "Preprocessing: Transcoding and silence detection...", "segmentsExtracted": "{count} segments extracted ({lang})", "@segmentsExtracted": { "placeholders": { diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index f8a1f60..b7a2a58 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -257,9 +257,15 @@ abstract class AppLocalizations { /// No description provided for @processingTranscription. /// /// In en, this message translates to: - /// **'Whisper is processing...'** + /// **'Transcription in progress...'** String get processingTranscription; + /// No description provided for @preprocessingStatus. + /// + /// In en, this message translates to: + /// **'Preprocessing: Transcoding and silence detection...'** + String get preprocessingStatus; + /// No description provided for @segmentsExtracted. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 5052eb0..4f4a6a3 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -89,7 +89,11 @@ class AppLocalizationsEn extends AppLocalizations { String get extractingAudio => 'Extracting audio from video...'; @override - String get processingTranscription => 'Whisper is processing...'; + String get processingTranscription => 'Transcription in progress...'; + + @override + String get preprocessingStatus => + 'Preprocessing: Transcoding and silence detection...'; @override String segmentsExtracted(int count, String lang) { diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index 66c3f83..03761d2 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -89,7 +89,10 @@ class AppLocalizationsZh extends AppLocalizations { String get extractingAudio => '正在从视频中提取音频...'; @override - String get processingTranscription => 'Whisper 正在处理中...'; + String get processingTranscription => '字幕转录中...'; + + @override + String get preprocessingStatus => '预处理:转码和静音检测中...'; @override String segmentsExtracted(int count, String lang) { diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 4f0ae12..17b377a 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -26,7 +26,8 @@ "extract": "提取", "downloadingModel": "正在下载模型 {name}...", "extractingAudio": "正在从视频中提取音频...", - "processingTranscription": "Whisper 正在处理中...", + "processingTranscription": "字幕转录中...", + "preprocessingStatus": "预处理:转码和静音检测中...", "segmentsExtracted": "已提取 {count} 条字幕段 ({lang})", "stepTranslate": "翻译", "geminiApiKey": "API Key", diff --git a/lib/services/whisper/whisper_service.dart b/lib/services/whisper/whisper_service.dart index 2fe6a93..8914ac0 100644 --- a/lib/services/whisper/whisper_service.dart +++ b/lib/services/whisper/whisper_service.dart @@ -49,6 +49,7 @@ class WhisperService { Future transcribe( String mediaPath, { String language = 'auto', + void Function(int progress)? onProgress, }) async { if (_currentModel == null) { throw StateError('No model loaded. Call loadModel() first.'); @@ -60,6 +61,7 @@ class WhisperService { lang: language, withTimestamps: true, convert: true, // Auto-convert via registered FFmpeg converter + onProgress: onProgress, ); if (result == null) { diff --git a/lib/ui/widgets/transcription_panel.dart b/lib/ui/widgets/transcription_panel.dart index bf2dade..37dbc41 100644 --- a/lib/ui/widgets/transcription_panel.dart +++ b/lib/ui/widgets/transcription_panel.dart @@ -139,11 +139,15 @@ class TranscriptionPanel extends StatelessWidget { } if (state is Transcribing) { + final s = state as Transcribing; + String label = s.progress > 0 + ? l10n.processingTranscription + : l10n.preprocessingStatus; return _buildProgressRow( context, icon: Icons.mic_rounded, - label: l10n.processingTranscription, - progress: null, + label: label, + progress: s.progress > 0 ? s.progress / 100.0 : null, color: Colors.purple, ); } @@ -240,10 +244,7 @@ class TranscriptionPanel extends StatelessWidget { width: 80, child: Text( info.name, - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 13, - ), + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13), ), ), _buildModelSpecColumn(l10n.diskUsage, info.diskUsage), @@ -267,10 +268,7 @@ class TranscriptionPanel extends StatelessWidget { color: Colors.white.withValues(alpha: 0.5), ), ), - Text( - value, - style: const TextStyle(fontSize: 12), - ), + Text(value, style: const TextStyle(fontSize: 12)), ], ), ); diff --git a/pubspec.lock b/pubspec.lock index 13cf8ab..ffb0605 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -880,7 +880,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: b57159c40d3356e51b32279c6cab12a9cb65cde3 + resolved-ref: "649e41882878f2d04d3b087d907161fdb7a2681b" url: "https://github.com/cddqssc/whisper_ggml_plus.git" source: git version: "1.4.1"