fix:增加html测试
This commit is contained in:
parent
cd63c0924b
commit
bb682226af
BIN
assets/demo.h264
Normal file
BIN
assets/demo.h264
Normal file
Binary file not shown.
2684
assets/html/h264.html
Normal file
2684
assets/html/h264.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
assets/talk.h264
Normal file
BIN
assets/talk.h264
Normal file
Binary file not shown.
@ -2,6 +2,7 @@ import 'package:get/get.dart';
|
||||
import 'package:star_lock/common/safetyVerification/safetyVerification_binding.dart';
|
||||
import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/login/forgetPassword/starLock_forgetPassword_xhj_page.dart';
|
||||
import 'package:star_lock/login/login/JMuxerApp.dart';
|
||||
import 'package:star_lock/login/login/starLock_login_xhj_page.dart';
|
||||
import 'package:star_lock/login/register/starLock_register_binding.dart';
|
||||
import 'package:star_lock/login/register/starLock_register_xhj_page.dart';
|
||||
@ -397,6 +398,7 @@ abstract class Routers {
|
||||
static const String ownedKeyListPage = '/ownedKeyListPage'; //拥有的钥匙
|
||||
|
||||
static const String starLockLoginPage = '/StarLockLoginPage'; // 登录
|
||||
static const String LocalHtmlPage = '/LocalHtmlPage'; // LocalHtmlPage
|
||||
static const String starLockRegisterPage = '/StarLockRegisterPage'; // 注册
|
||||
static const String starLockForgetPasswordPage =
|
||||
'/StarLockForgetPasswordPage'; // 忘记密码
|
||||
@ -638,6 +640,9 @@ abstract class AppRouters {
|
||||
page: () => F.sw(
|
||||
skyCall: () => const StarLockLoginPage(),
|
||||
xhjCall: () => const StarLockLoginXHJPage()),
|
||||
),GetPage<dynamic>(
|
||||
name: Routers.LocalHtmlPage,
|
||||
page: () => LocalHtmlPage(),
|
||||
),
|
||||
GetPage<dynamic>(
|
||||
name: Routers.starLockRegisterPage,
|
||||
|
||||
137
lib/login/login/JMuxerApp.dart
Normal file
137
lib/login/login/JMuxerApp.dart
Normal file
@ -0,0 +1,137 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart' show ByteData, Uint8List, rootBundle;
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class LocalHtmlPage extends StatefulWidget {
|
||||
@override
|
||||
_LocalHtmlPageState createState() => _LocalHtmlPageState();
|
||||
}
|
||||
|
||||
class _LocalHtmlPageState extends State<LocalHtmlPage> {
|
||||
late final WebViewController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..enableZoom(false)
|
||||
..addJavaScriptChannel(
|
||||
'Flutter',
|
||||
onMessageReceived: (message) {
|
||||
print("来自 HTML 的消息: ${message.message}");
|
||||
},
|
||||
);
|
||||
|
||||
// 加载本地 HTML
|
||||
_loadLocalHtml();
|
||||
_sendFramesToHtml();
|
||||
}
|
||||
|
||||
void _sendFramesToHtml() async {
|
||||
// 读取 assets/demo.h264 文件
|
||||
final ByteData data = await rootBundle.load('assets/talk.h264');
|
||||
final List<int> byteData = data.buffer.asUint8List();
|
||||
|
||||
int offset = 0;
|
||||
int frameSize = 0;
|
||||
|
||||
// 根据 H.264 数据的帧结构来逐帧读取并发送
|
||||
while (offset < byteData.length) {
|
||||
// 获取每一帧的大小
|
||||
frameSize = getFrameSize(byteData, offset);
|
||||
|
||||
if (frameSize == 0) {
|
||||
print("No more frames or error in frame size calculation.");
|
||||
break; // 如果没有更多的帧,或者无法计算帧的大小,则退出循环
|
||||
}
|
||||
|
||||
// 提取当前帧数据
|
||||
List<int> frameData = byteData.sublist(offset, offset + frameSize);
|
||||
|
||||
// 将当前帧数据发送到 WebView 中的 feedDataFromFlutter 函数
|
||||
String jsCode = "feedDataFromFlutter(${frameData});";
|
||||
await _controller.runJavaScript(jsCode);
|
||||
|
||||
// 更新偏移量,继续发送下一个帧
|
||||
offset += frameSize;
|
||||
|
||||
// 控制帧率,模拟每秒 22 帧播放(或者根据你的视频帧率调整)
|
||||
await Future.delayed(Duration(milliseconds: (1000 / 22).toInt()));
|
||||
}
|
||||
}
|
||||
|
||||
int getFrameSize(List<int> data, int offset) {
|
||||
// 查找第一个 Start Code (0x000001 或 0x00000001)
|
||||
const List<int> startCode1 = [0, 0, 0, 1]; // Start Code: 0x000001
|
||||
const List<int> startCode2 = [
|
||||
0,
|
||||
0,
|
||||
1
|
||||
]; // Start Code: 0x000001 (0x00000001 version)
|
||||
|
||||
// 查找下一个 Start Code 的位置
|
||||
int startCodeStart = -1;
|
||||
int startCodeEnd = -1;
|
||||
for (int i = offset; i < data.length - 3; i++) {
|
||||
// 判断是否匹配 Start Code (0x000001 或 0x00000001)
|
||||
if (_matchesStartCode(data, i, startCode1)) {
|
||||
startCodeStart = i;
|
||||
startCodeEnd = i + startCode1.length;
|
||||
break;
|
||||
} else if (_matchesStartCode(data, i, startCode2)) {
|
||||
startCodeStart = i;
|
||||
startCodeEnd = i + startCode2.length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找不到有效的 Start Code,返回 0(结束循环)
|
||||
if (startCodeStart == -1) return 0;
|
||||
|
||||
// 查找下一个 Start Code 的位置
|
||||
int nextStartCodeStart = -1;
|
||||
for (int i = startCodeEnd; i < data.length - 3; i++) {
|
||||
if (_matchesStartCode(data, i, startCode1) ||
|
||||
_matchesStartCode(data, i, startCode2)) {
|
||||
nextStartCodeStart = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果找不到下一个 Start Code,说明当前是最后一个 NAL 单元
|
||||
if (nextStartCodeStart == -1) {
|
||||
return data.length - startCodeStart;
|
||||
}
|
||||
|
||||
// 计算并返回当前 NAL 单元的大小
|
||||
return nextStartCodeStart - startCodeStart;
|
||||
}
|
||||
|
||||
// 检查数据是否匹配 Start Code
|
||||
bool _matchesStartCode(List<int> data, int index, List<int> startCode) {
|
||||
for (int i = 0; i < startCode.length; i++) {
|
||||
if (data[index + i] != startCode[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> _loadLocalHtml() async {
|
||||
final String fileHtmlContent =
|
||||
await rootBundle.loadString('assets/html/h264.html');
|
||||
_controller.loadHtmlString(fileHtmlContent);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text("加载本地 HTML"),
|
||||
),
|
||||
body: WebViewWidget(controller: _controller),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -238,18 +238,23 @@ class _StarLockLoginPageState extends State<StarLockLoginPage> {
|
||||
SubmitBtn(
|
||||
btnName: '发送回声测试消息',
|
||||
onClick: () {
|
||||
StartChartManage().sendEchoMessage(
|
||||
ToPeerId: '3phX8Ng2cZHz5NtP8xAf6nYy2z1BYytoejgjoHrWMGhH');
|
||||
StartChartManage().sendEchoMessage();
|
||||
},
|
||||
),
|
||||
SubmitBtn(
|
||||
btnName: '发送对讲请求1',
|
||||
onClick: () {
|
||||
StartChartManage().sendCallRequestMessage(
|
||||
ToPeerId: 'CqKJUADeUZsHrSD4SEVnPBr73fbsHNUXCEq9kyCtE3wp',
|
||||
ToPeerId: '3QvLvD3cBnM358bCdccUpGBBYicepEskPXEsh8KvTvY2',
|
||||
);
|
||||
},
|
||||
),
|
||||
SubmitBtn(
|
||||
btnName: '跳转至html',
|
||||
onClick: () {
|
||||
Get.toNamed(Routers.LocalHtmlPage);
|
||||
},
|
||||
),
|
||||
SizedBox(height: 50.w),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
|
||||
@ -36,7 +36,6 @@ class UdpTalkAcceptHandler extends ScpMessageBaseHandle
|
||||
stopRingtone();
|
||||
// 设置状态为接听中
|
||||
talkStatus.setDuringCall();
|
||||
stopRingtone();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -176,6 +176,7 @@ class StartChartManage {
|
||||
|
||||
// 发送上线消息
|
||||
Future<void> _sendOnlineMessage() async {
|
||||
_log(text: '发送上线消息');
|
||||
if (isOnlineStartChartServer) {
|
||||
_log(text: '星图已上线,请勿重复发送上线消息');
|
||||
return;
|
||||
@ -190,6 +191,10 @@ class StartChartManage {
|
||||
|
||||
// 发送对讲请求消息
|
||||
Future<void> sendCallRequestMessage({required String ToPeerId}) async {
|
||||
if (talkStatus.status == TalkStatus.duringCall) {
|
||||
_log(text: '已经在通话中,请勿重复发送对讲请求');
|
||||
return;
|
||||
}
|
||||
// 组装上线消息
|
||||
final message = MessageCommand.talkRequestMessage(
|
||||
FromPeerId: FromPeerId,
|
||||
@ -220,12 +225,13 @@ class StartChartManage {
|
||||
}
|
||||
|
||||
// 发送回声测试消息
|
||||
void sendEchoMessage({required String ToPeerId}) async {
|
||||
void sendEchoMessage() async {
|
||||
final message = MessageCommand.echoMessage(
|
||||
ToPeerId: ToPeerId,
|
||||
ToPeerId: echoPeerId,
|
||||
FromPeerId: FromPeerId,
|
||||
);
|
||||
await _sendMessage(message: message);
|
||||
_log(text: '发送回声测试消息');
|
||||
}
|
||||
|
||||
// 发送网关初始化消息
|
||||
@ -704,7 +710,6 @@ class StartChartManage {
|
||||
seconds: talkPingIntervalTime,
|
||||
),
|
||||
(Timer timer) async {
|
||||
// 重新发送上线消息
|
||||
await sendTalkPingMessage(
|
||||
ToPeerId: ToPeerId,
|
||||
FromPeerId: FromPeerId,
|
||||
|
||||
@ -4,6 +4,7 @@ import 'package:star_lock/talk/startChart/events/talk_status_change_event.dart';
|
||||
|
||||
enum TalkStatus {
|
||||
waitingAnswer, // 等待接听
|
||||
waitingData, // 等待数据
|
||||
duringCall, // 通话中
|
||||
rejected, // 被拒绝
|
||||
uninitialized, // 未初始化
|
||||
|
||||
@ -298,6 +298,9 @@ flutter:
|
||||
- images/mine/
|
||||
- images/lockType/
|
||||
- assets/
|
||||
- assets/html/h264.html
|
||||
- assets/demo.h264
|
||||
- assets/talk.h264
|
||||
- lan/
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user