@@ -45,6 +45,11 @@ class AudioHapticsService {
4545 String ? _activeStreamSource;
4646 String ? _activeStreamFinalSource;
4747 bool _activeStreamSourceIsGrowing = false ;
48+ bool _loggedFirstStreamingChunk = false ;
49+ bool _loggedNoEventChunk = false ;
50+ bool _loggedFirstStreamingEventBatch = false ;
51+ bool _platformPulseFailureLogged = false ;
52+ bool _timerStartLogged = false ;
4853
4954 bool get enabled => _enabled;
5055 bool get _supportsPlatform => Platform .isIOS || Platform .isAndroid;
@@ -61,9 +66,22 @@ class AudioHapticsService {
6166 required bool enabled,
6267 required double intensity,
6368 }) async {
69+ final previousEnabled = _enabled;
70+ final previousIntensity = _intensity;
6471 _enabled = enabled && _supportsPlatform;
6572 _intensity = intensity.clamp (0.2 , 1.0 );
6673
74+ if (previousEnabled != _enabled ||
75+ (previousIntensity - _intensity).abs () > 0.001 ||
76+ enabled != _enabled) {
77+ _hapticsLog.info (
78+ '设置更新: requested=$enabled , effective=$_enabled , '
79+ 'supported=$_supportsPlatform , intensity=${_intensity .toStringAsFixed (2 )}, '
80+ 'platform=${Platform .operatingSystem }' ,
81+ tag: 'AudioHaptics' ,
82+ );
83+ }
84+
6785 if (! _enabled) {
6886 await stop (clearSource: false );
6987 return ;
@@ -91,6 +109,7 @@ class AudioHapticsService {
91109 _activeStreamFinalSource = null ;
92110 _activeStreamSourceIsGrowing = false ;
93111 _streamingPatternGenerator = null ;
112+ _resetDiagnosticsForNewAnalysis ();
94113
95114 if (! _enabled) return ;
96115
@@ -105,6 +124,11 @@ class AudioHapticsService {
105124 final generation = _analysisGeneration;
106125
107126 try {
127+ _hapticsLog.info (
128+ '开始完整文件分析: title="${track .title }", path=${_shortPath (path )}, '
129+ 'file=${await _fileState (path )}' ,
130+ tag: 'AudioHaptics' ,
131+ );
108132 final raw = await _channel.invokeMethod <Map <dynamic , dynamic >>(
109133 'analyze' ,
110134 {
@@ -123,8 +147,10 @@ class AudioHapticsService {
123147 _nextEventIndex = _indexForPosition (
124148 _positionProvider? .call () ?? Duration .zero,
125149 );
126- _hapticsLog.captureOutput (
127- '[AudioHaptics] 已生成 ${_events .length } 个触感事件: ${track .title }' ,
150+ _hapticsLog.info (
151+ '完整分析完成: title="${track .title }", frames=${analysis .energies .length }, '
152+ 'events=${_events .length }, startIndex=$_nextEventIndex ' ,
153+ tag: 'AudioHaptics' ,
128154 );
129155 if (_playingProvider? .call () ?? false ) {
130156 start ();
@@ -150,6 +176,7 @@ class AudioHapticsService {
150176 _activeStreamSource = source;
151177 _activeStreamFinalSource = finalSource;
152178 _activeStreamSourceIsGrowing = growingFile;
179+ _resetDiagnosticsForNewAnalysis ();
153180 _streamingPatternGenerator = StreamingAudioHapticPatternGenerator (
154181 frameMs: AudioHapticPatternGenerator .defaultFrameMs,
155182 userIntensity: _intensity,
@@ -163,6 +190,14 @@ class AudioHapticsService {
163190 final method =
164191 growingFile ? 'startGrowingFileAnalysis' : 'startFileStreamAnalysis' ;
165192 try {
193+ _hapticsLog.info (
194+ '准备流式分析: title="${track .title }", method=$method , '
195+ 'source=${_shortPath (source )}, sourceFile=${await _fileState (source )}, '
196+ 'finalSource=${_shortPath (finalSource )}, '
197+ 'finalFile=${finalSource == null ? 'none' : await _fileState (finalSource )}, '
198+ 'start=${startPosition .inMilliseconds }ms' ,
199+ tag: 'AudioHaptics' ,
200+ );
166201 await _channel.invokeMethod <void >(method, {
167202 'path' : source,
168203 if (finalSource != null ) 'finalPath' : finalSource,
@@ -172,8 +207,9 @@ class AudioHapticsService {
172207 'analysisToken' : generation,
173208 });
174209 if (generation == _analysisGeneration) {
175- _hapticsLog.captureOutput (
176- '[AudioHaptics] 已启动流式分析: ${track .title }' ,
210+ _hapticsLog.info (
211+ '已启动流式分析: title="${track .title }", token=$generation ' ,
212+ tag: 'AudioHaptics' ,
177213 );
178214 }
179215 } catch (e) {
@@ -188,6 +224,14 @@ class AudioHapticsService {
188224 if (! _enabled || _events.isEmpty) return ;
189225 if (_timer? .isActive ?? false ) return ;
190226 _timer? .cancel ();
227+ if (! _timerStartLogged) {
228+ _hapticsLog.info (
229+ '触感定时器启动: events=${_events .length }, '
230+ 'position=${(_positionProvider ?.call () ?? Duration .zero ).inMilliseconds }ms' ,
231+ tag: 'AudioHaptics' ,
232+ );
233+ _timerStartLogged = true ;
234+ }
191235 _timer = Timer .periodic (const Duration (milliseconds: 24 ), (_) {
192236 unawaited (_tick ());
193237 });
@@ -206,6 +250,7 @@ class AudioHapticsService {
206250 _nextEventIndex = 0 ;
207251 _analysisGeneration++ ;
208252 _streamingPatternGenerator = null ;
253+ _resetDiagnosticsForNewAnalysis ();
209254 if (clearSource) {
210255 _activeStreamSource = null ;
211256 _activeStreamFinalSource = null ;
@@ -261,7 +306,14 @@ class AudioHapticsService {
261306 'intensity' : event.intensity,
262307 'durationMs' : event.durationMs,
263308 });
264- } catch (_) {
309+ } catch (e) {
310+ if (! _platformPulseFailureLogged) {
311+ _hapticsLog.warning (
312+ '平台触感脉冲调用失败,后续同一分析周期内不再重复记录: $e ' ,
313+ tag: 'AudioHaptics' ,
314+ );
315+ _platformPulseFailureLogged = true ;
316+ }
265317 // Platform haptics are best-effort; never interrupt audio playback.
266318 }
267319 }
@@ -281,6 +333,12 @@ class AudioHapticsService {
281333 '[AudioHaptics] 流式分析失败: ${_analysisMessage (call .arguments )}' ,
282334 );
283335 return null ;
336+ case 'diagnostic' :
337+ _hapticsLog.info (
338+ _analysisMessage (call.arguments),
339+ tag: 'AudioHaptics' ,
340+ );
341+ return null ;
284342 default :
285343 throw MissingPluginException (
286344 'Unknown audio haptics method: ${call .method }' );
@@ -296,11 +354,40 @@ class AudioHapticsService {
296354 if (generator == null ) return ;
297355 generator.userIntensity = _intensity;
298356
357+ if (! _loggedFirstStreamingChunk) {
358+ _hapticsLog.info (
359+ '收到首个分析块: startFrame=${analysis .startFrame }, '
360+ 'frameMs=${analysis .frameMs }, energies=${analysis .energies .length }, '
361+ 'energyRange=${_energyRange (analysis .energies )}' ,
362+ tag: 'AudioHaptics' ,
363+ );
364+ _loggedFirstStreamingChunk = true ;
365+ }
366+
299367 final newEvents = generator.append (
300368 startFrame: analysis.startFrame,
301369 energies: analysis.energies,
302370 );
303- if (newEvents.isEmpty) return ;
371+ if (newEvents.isEmpty) {
372+ if (! _loggedNoEventChunk) {
373+ _hapticsLog.info (
374+ '分析块暂未产生触感事件,可能是音量/动态不足: '
375+ 'startFrame=${analysis .startFrame }, energies=${analysis .energies .length }' ,
376+ tag: 'AudioHaptics' ,
377+ );
378+ _loggedNoEventChunk = true ;
379+ }
380+ return ;
381+ }
382+
383+ if (! _loggedFirstStreamingEventBatch) {
384+ _hapticsLog.info (
385+ '生成首批流式触感事件: count=${newEvents .length }, '
386+ 'first=${newEvents .first .timeMs }ms, last=${newEvents .last .timeMs }ms' ,
387+ tag: 'AudioHaptics' ,
388+ );
389+ _loggedFirstStreamingEventBatch = true ;
390+ }
304391
305392 _events = [..._events, ...newEvents];
306393 if (_playingProvider? .call () ?? false ) {
@@ -348,6 +435,42 @@ class AudioHapticsService {
348435 return null ;
349436 }
350437
438+ void _resetDiagnosticsForNewAnalysis () {
439+ _loggedFirstStreamingChunk = false ;
440+ _loggedNoEventChunk = false ;
441+ _loggedFirstStreamingEventBatch = false ;
442+ _platformPulseFailureLogged = false ;
443+ _timerStartLogged = false ;
444+ }
445+
446+ String _shortPath (String ? path) {
447+ if (path == null || path.isEmpty) return 'none' ;
448+ if (path.length <= 96 ) return path;
449+ return '...${path .substring (path .length - 96 )}' ;
450+ }
451+
452+ Future <String > _fileState (String path) async {
453+ try {
454+ final file = File (path);
455+ if (! await file.exists ()) return 'missing' ;
456+ final length = await file.length ();
457+ return 'exists:${length }B' ;
458+ } catch (e) {
459+ return 'error:$e ' ;
460+ }
461+ }
462+
463+ String _energyRange (List <double > energies) {
464+ if (energies.isEmpty) return 'empty' ;
465+ var minValue = energies.first;
466+ var maxValue = energies.first;
467+ for (final energy in energies.skip (1 )) {
468+ if (energy < minValue) minValue = energy;
469+ if (energy > maxValue) maxValue = energy;
470+ }
471+ return '${minValue .toStringAsFixed (3 )}-${maxValue .toStringAsFixed (3 )}' ;
472+ }
473+
351474 Future <void > _stopPlatformHaptics () async {
352475 if (! _supportsPlatform) return ;
353476 try {
0 commit comments