mirror of
https://github.com/cuteLittleDevil/m7s-jt1078.git
synced 2025-12-24 13:29:23 +08:00
290 lines
12 KiB
HTML
290 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>WebRTC WHIP Audio Sender</title>
|
|
</head>
|
|
|
|
<body>
|
|
<label for="newUrl">808 url:</label>
|
|
<input type="text" id="newUrl" value="https://124.221.30.46:12000/api/v1/jt808/9101" style="width: 300px;">
|
|
<label for="ip">ip:</label>
|
|
<input type="text" id="ip" value="124.221.30.46">
|
|
<label for="port">port:</label>
|
|
<input type="text" id="port" value="12051">
|
|
<label for="simCard">sim:</label>
|
|
<input type="text" id="simCard" value="10088">
|
|
<button id="newSendButton">设备音视频指令</button>
|
|
<div id="newStatus"></div>
|
|
<label for="audioPort">音频端口:</label>
|
|
<input type="text" id="audioPort" value="12022">
|
|
<button id="intercomSendButton">设备对讲指令</button>
|
|
<div id="intercomStatus"></div>
|
|
<label for="url">url:</label>
|
|
<input type="text" id="url" value="https://124.221.30.46:12080/jt1078/api/v1/intercom" style="width: 300px;">
|
|
<label for="portsInput">音频端口组第一个:</label>
|
|
<input type="text" id="portsInput" value="12022" style="width: 100px;">
|
|
<label for="audioTextBox">音频类型文本框:</label>
|
|
<input type="text" id="audioTextBox" value="https://124.221.30.46:12000/api/v1/jt808/9003" style="width: 300px;">
|
|
<button id="startButton">webrtc对讲</button>
|
|
<button id="stopButton" disabled>关闭webrtc对讲</button>
|
|
<div id="status"></div>
|
|
<video id="videoElement" width="640" height="360" controls></video>
|
|
|
|
<!-- https://github.com/bilibili/flv.js/releases-->
|
|
<script src="flv.min.js"></script>
|
|
|
|
<script>
|
|
const startButton = document.getElementById('startButton');
|
|
const stopButton = document.getElementById('stopButton');
|
|
const statusDiv = document.getElementById('status');
|
|
let peerConnection;
|
|
let mediaStream;
|
|
|
|
async function startSendingAudio() {
|
|
try {
|
|
const simCard = document.getElementById('simCard').value;
|
|
const newUrl = document.getElementById('audioTextBox').value;
|
|
const newResponse = await fetch(newUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
key: simCard,
|
|
data:{}
|
|
})
|
|
});
|
|
if (!newResponse.ok) {
|
|
throw new Error(`HTTP error! status: ${newResponse.status}`);
|
|
}
|
|
const newData = await newResponse.json();
|
|
console.log(newData)
|
|
const audio = newData.data.details.enterAudioEncoding
|
|
console.log("音频类型 2-G722 6-G711A 7-G711U 当前值:"+audio)
|
|
console.log("输入音频采样位数 0-8位 1-16位 2-32位 当前值:"+newData.data.details.enterAudioSampleDigits)
|
|
console.log("输入音频采样率 0-8kHz 1-22.05 kHz 2-44.1 kHz 3-48 kHz 当前值:"+newData.data.details.enterAudioSampleRate)
|
|
console.log("音频帧长度 范围1-4294967295 当前值:"+newData.data.details.audioFrameLength)
|
|
|
|
statusDiv.textContent = `音频类型:` + audio;
|
|
|
|
// 获取音频流
|
|
mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
audio: {
|
|
echoCancellation: true, // 启用回声消除
|
|
noiseSuppression: true, // 启用噪声抑制
|
|
autoGainControl: true, // 启用自动增益控制
|
|
channelCount: 1, // 使用单声道减少处理复杂度
|
|
sampleRate: 8000, // 设置合适的采样率
|
|
sampleSize: 16, // 位深度
|
|
}
|
|
});
|
|
|
|
// 创建 RTCPeerConnection 实例
|
|
peerConnection = new RTCPeerConnection();
|
|
|
|
// 将音频轨道添加到连接中
|
|
mediaStream.getTracks().forEach(track => {
|
|
peerConnection.addTrack(track, mediaStream);
|
|
});
|
|
peerConnection.addEventListener('icecandidate', handleConnection);
|
|
|
|
// 创建一个 offer
|
|
const offer = await peerConnection.createOffer();
|
|
await peerConnection.setLocalDescription(offer);
|
|
const url = document.getElementById('url').value;
|
|
const audioPort = document.getElementById('portsInput').value;
|
|
const response = await fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
sdp: offer.sdp,
|
|
group: [
|
|
{
|
|
sim: simCard,
|
|
channel: 1,
|
|
audioPort: parseInt(audioPort, 10)
|
|
}
|
|
],
|
|
// EnterAudioEncoding 音频类型参数 根据jt1078-2016表12 2-G722 6-G711A 7-G711U
|
|
enterAudioEncoding: parseInt(audio, 10)
|
|
})
|
|
});
|
|
console.log(response.ok)
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
const answer = new RTCSessionDescription({ type: data.type, sdp: data.sdp });
|
|
await peerConnection.setRemoteDescription(answer);
|
|
|
|
startButton.disabled = true;
|
|
stopButton.disabled = false;
|
|
statusDiv.textContent = '开始对讲';
|
|
|
|
|
|
} catch (error) {
|
|
console.error('Error starting audio sending:', error);
|
|
statusDiv.textContent = `Error: ${error.message}`;
|
|
}
|
|
}
|
|
|
|
async function stopSendingAudio() {
|
|
if (peerConnection) {
|
|
// 发送关闭请求到服务器
|
|
try {
|
|
const simCard = document.getElementById('simCard').value;
|
|
// 设备和jt1078之间的链接 手动关闭 或者设置超时自动关闭
|
|
const url = 'https://124.221.30.46:12000/api/v1/jt808/9102'
|
|
const response = await fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
key: simCard,
|
|
data: {
|
|
channelNo: 1,
|
|
controlCmd: 4,
|
|
closeAudioVideoData: 0,
|
|
streamType: 0
|
|
}
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('关闭请求响应:', data);
|
|
statusDiv.textContent += ' (服务器已通知)';
|
|
} catch (error) {
|
|
console.error('Error sending stop request:', error);
|
|
statusDiv.textContent += ' (关闭请求失败)';
|
|
}
|
|
|
|
peerConnection.close();
|
|
peerConnection = null;
|
|
}
|
|
if (mediaStream) {
|
|
mediaStream.getTracks().forEach(track => track.stop());
|
|
mediaStream = null;
|
|
}
|
|
startButton.disabled = false;
|
|
stopButton.disabled = true;
|
|
statusDiv.textContent = '关闭对讲';
|
|
}
|
|
|
|
startButton.addEventListener('click', startSendingAudio);
|
|
stopButton.addEventListener('click', stopSendingAudio);
|
|
|
|
function handleConnection(event) {
|
|
const iceCandidate = event.candidate;
|
|
if (iceCandidate) {
|
|
const newIceCandidate = new RTCIceCandidate(iceCandidate);
|
|
console.log(newIceCandidate)
|
|
console.log(`ICE candidate:\n` +
|
|
`${event.candidate.candidate}.`)
|
|
}
|
|
}
|
|
|
|
const newSendButton = document.getElementById('newSendButton');
|
|
const newStatusDiv = document.getElementById('newStatus');
|
|
async function sendNewRequest() {
|
|
const newUrl = document.getElementById('newUrl').value;
|
|
const ip = document.getElementById('ip').value;
|
|
const port = parseInt(document.getElementById('port').value, 10);
|
|
const simCard = document.getElementById('simCard').value;
|
|
try {
|
|
const response = await fetch(newUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
key: simCard,
|
|
data: {
|
|
serverIPAddr: ip,
|
|
serverIPLen: ip.length,
|
|
tcpPort: port,
|
|
channelNo: 1, // 通道号
|
|
// 选择0音视频的情况 因为音频是g711a flv支持不了
|
|
dataType: 1, // 0-音视频 1-视频 2-双向对讲 3-监听 4-中心广播 5-透传
|
|
streamType: 0, // 0-主码流 1-子码流
|
|
}
|
|
})
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
// http://124.221.30.46:12080/mp4/live/jt1078-10088-1.mp4
|
|
// https://go-jt808.online:12080/flv/live/jt1078-10088-1.flv
|
|
data.playUrl = `https://${ip}:12080/flv/live/jt1078-${simCard}-1.flv`;
|
|
newStatusDiv.innerHTML = `<pre>请求成功: ${JSON.stringify(data, null, 2)}</pre>`; // 格式化显示JSON
|
|
setTimeout(() => {
|
|
console.log('等待设备推流 假设3秒内完成');
|
|
const videoElement = document.getElementById('videoElement');
|
|
const flvPlayer = flvjs.createPlayer({
|
|
type: 'flv',
|
|
url: data.playUrl
|
|
});
|
|
flvPlayer.attachMediaElement(videoElement);
|
|
flvPlayer.load();
|
|
flvPlayer.play();
|
|
}, 3000);
|
|
} catch (error) {
|
|
console.error('Error sending new request:', error);
|
|
newStatusDiv.innerHTML = `<pre>Error: ${error.message}</pre>`; // 格式化显示错误信息
|
|
}
|
|
}
|
|
|
|
newSendButton.addEventListener('click', sendNewRequest);
|
|
|
|
const intercomSendButton = document.getElementById('intercomSendButton');
|
|
const intercomStatusDiv = document.getElementById('intercomStatus');
|
|
|
|
async function sendIntercomRequest() {
|
|
const newUrl = document.getElementById('newUrl').value;
|
|
const ip = document.getElementById('ip').value;
|
|
const audioPort = parseInt(document.getElementById('audioPort').value, 10);
|
|
const simCard = document.getElementById('simCard').value;
|
|
try {
|
|
const response = await fetch(newUrl, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
key: simCard,
|
|
data: {
|
|
serverIPAddr: ip,
|
|
serverIPLen: ip.length,
|
|
tcpPort: audioPort,
|
|
channelNo: 1, // 通道号
|
|
dataType: 2, // 0-音视频 1-视频 2-双向对讲 3-监听 4-中心广播 5-透传
|
|
streamType: 0, // 0-主码流 1-子码流
|
|
}
|
|
})
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
intercomStatusDiv.innerHTML = `<pre>请求成功: ${JSON.stringify(data, null, 2)}</pre>`; // 格式化显示JSON
|
|
} catch (error) {
|
|
console.error('Error sending intercom request:', error);
|
|
intercomStatusDiv.innerHTML = `<pre>Error: ${error.message}</pre>`; // 格式化显示错误信息
|
|
}
|
|
}
|
|
|
|
intercomSendButton.addEventListener('click', sendIntercomRequest);
|
|
</script>
|
|
</body>
|
|
|
|
</html> |