import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/services.dart'; import 'package:hgdj/config/config.dart'; import 'package:hgdj/hj_utils/codec_support.dart'; import 'package:hgdj/hj_utils/video_view_type.dart'; import 'package:hgdj/tools_base/global_store/store.dart'; import 'package:hgdj/tools_base/net/http_manager.dart'; import 'package:hgdj/tools_base/toast.dart'; import 'package:hgdj/track_event_manager/device_service.dart'; /// 播放失败诊断(**测试包专用**)。 /// /// 播放失败时把现场信息拼成文本复制到剪贴板,让用户直接粘贴发回来—— /// release 包里 debugLog/print 全不输出,这类"只有某台机器复现"的反馈没别的抓手。 /// /// 用法:失败分支调 [PlayDiagnose.report],开关见 [Config.playDiagnose]。 class PlayDiagnose { PlayDiagnose._(); /// 最近几条失败记录:用户常连点几个视频都失败,一次把全部给出来才看得出是否同因 static final List _records = []; static const _maxRecords = 5; /// 记录一次播放失败,并把累计记录复制到剪贴板。 /// [scene] 场景(长视频/短视频/短剧)、[error] 原始异常、[url] 当次播放地址 static Future report({ required String scene, required Object? error, String? url, String? videoId, String? videoTitle, bool? isH265, bool? forceH264, }) async { if (!Config.playDiagnose) return; final net = await _netDesc(); final buffer = StringBuffer() ..writeln('【$scene】${DateTime.now()}') ..writeln('视频: ${videoTitle ?? '-'} (id=${videoId ?? '-'})') ..writeln('地址: ${url ?? '-'}') ..writeln( '本次选流: ${isH265 == true ? 'H265' : 'H264'} 已回退264=${forceH264 ?? false}') ..writeln('--- 编解码 ---') ..writeln( '芯片硬解265=${CodecSupport.hwSupport} 本机已禁265=${CodecSupport.deviceDisabled} 最终用265=${CodecSupport.useH265}') ..writeln( '渲染方式=${needPlatformView ? 'platformView' : 'textureView'} 已持久化=$platformViewPersisted') ..writeln('判定为解码错误=${isDecoderError(error)}') ..writeln('--- 环境 ---') ..writeln( '机型: ${DeviceInfoService.brand} ${DeviceInfoService.model} 系统: ${DeviceInfoService.deviceOS} ${DeviceInfoService.systemVersion}') ..writeln( '版本: ${Config.innerVersion} 用户: ${globalStore.meInfo?.uid ?? '-'} 设备: ${DeviceInfoService.deviceId}') ..writeln('网络: $net 线路: ${httpManager.baseUrl}') ..writeln('--- 错误原文 ---') ..writeln('$error'); _records.add(buffer.toString()); if (_records.length > _maxRecords) _records.removeAt(0); await Clipboard.setData( ClipboardData(text: _records.join('\n${'=' * 30}\n'))); showToast('失败信息已复制(${_records.length}条)\n请粘贴发给客服'); } static Future _netDesc() async { try { final result = await Connectivity().checkConnectivity(); return result.toString().replaceAll('ConnectivityResult.', ''); } catch (e) { return 'unknown'; } } }