加入订阅测试页面

This commit is contained in:
dexter
2023-03-09 19:00:05 +08:00
parent 25af901499
commit 22cd7316f1
4 changed files with 137 additions and 35 deletions

View File

@@ -47,7 +47,8 @@ import (
//go:embed publish.html //go:embed publish.html
var publishHTML []byte var publishHTML []byte
//go:embed subscribe.html
var subscribeHTML []byte
var ( var (
reg_level = regexp.MustCompile("profile-level-id=(4.+f)") reg_level = regexp.MustCompile("profile-level-id=(4.+f)")
) )
@@ -144,7 +145,7 @@ func (conf *WebRTCConfig) Push_(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
// puber.SetIO(puber.PeerConnection) puber.SetIO(puber.PeerConnection) //TODO: 单PC需要注释掉
puber.OnICECandidate(func(ice *ICECandidate) { puber.OnICECandidate(func(ice *ICECandidate) {
if ice != nil { if ice != nil {
puber.Info(ice.ToJSON().Candidate) puber.Info(ice.ToJSON().Candidate)
@@ -206,7 +207,9 @@ func (conf *WebRTCConfig) Push_(w http.ResponseWriter, r *http.Request) {
func (conf *WebRTCConfig) Test_Publish(w http.ResponseWriter, r *http.Request) { func (conf *WebRTCConfig) Test_Publish(w http.ResponseWriter, r *http.Request) {
w.Write(publishHTML) w.Write(publishHTML)
} }
func (conf *WebRTCConfig) Test_Subscribe(w http.ResponseWriter, r *http.Request) {
w.Write(subscribeHTML)
}
var webrtcConfig WebRTCConfig var webrtcConfig WebRTCConfig
var WebRTCPlugin = engine.InstallPlugin(&webrtcConfig) var WebRTCPlugin = engine.InstallPlugin(&webrtcConfig)

View File

@@ -12,10 +12,20 @@
<video id="video" width="640" height="480" autoplay muted> <video id="video" width="640" height="480" autoplay muted>
</video> </video>
<!-- <button id="sw" onclick="action()" type="button" style="width:100px;height:30px;display: block;">unpublish</button> --> <!-- <button id="sw" onclick="action()" type="button" style="width:100px;height:30px;display: block;">unpublish</button> -->
<pre>
<code id="remoteSdp">
</code>
</pre>
</body> </body>
<script> <script>
let action = () => { console.log('action not set'); }; let action = () => { console.log('action not set'); };
(async () => { (async () => {
navigator.mediaDevices.enumerateDevices().then((devices) => {
devices.forEach((device) => {
console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
});
});
const mediaStream = await navigator.mediaDevices.getUserMedia({ const mediaStream = await navigator.mediaDevices.getUserMedia({
video: true, video: true,
audio: true, audio: true,
@@ -29,12 +39,13 @@
pc.onicecandidate = (e) => { pc.onicecandidate = (e) => {
console.log('onicecandidate', e.candidate); console.log('onicecandidate', e.candidate);
}; };
// mediaStream.getTracks().forEach((t) => { mediaStream.id = 'live/webrtc';
// pc.addTrack(t, mediaStream); mediaStream.getTracks().forEach((t) => {
// }); pc.addTrack(t, mediaStream);
let videoTransceiver = pc.addTransceiver(mediaStream.getVideoTracks()[0], { direction: 'sendonly' }); });
let audioTransceiver = pc.addTransceiver(mediaStream.getAudioTracks()[0], { direction: 'sendonly' }); // const videoTransceiver = pc.addTransceiver(mediaStream.getVideoTracks()[0], { direction: 'sendonly' });
const dc = pc.createDataChannel('sdp'); // const audioTransceiver = pc.addTransceiver(mediaStream.getAudioTracks()[0], { direction: 'sendonly' });
// const dc = pc.createDataChannel('sdp');
const offer = await pc.createOffer(); const offer = await pc.createOffer();
await pc.setLocalDescription(offer); await pc.setLocalDescription(offer);
const result = await fetch( const result = await fetch(
@@ -51,33 +62,34 @@
}, },
); );
const remoteSdp = await result.text(); const remoteSdp = await result.text();
document.getElementById('remoteSdp').innerText = remoteSdp;
await pc.setRemoteDescription( await pc.setRemoteDescription(
new RTCSessionDescription({ type: 'answer', sdp: remoteSdp }), new RTCSessionDescription({ type: 'answer', sdp: remoteSdp }),
); );
dc.onmessage = async (e) => { // dc.onmessage = async (e) => {
await pc.setRemoteDescription( // await pc.setRemoteDescription(
new RTCSessionDescription({ type: 'answer', sdp: e.data }), // new RTCSessionDescription({ type: 'answer', sdp: e.data }),
); // );
}; // };
const publish = async () => { // const publish = async () => {
videoTransceiver.direction = 'sendonly'; // videoTransceiver.direction = 'sendonly';
audioTransceiver.direction = 'sendonly'; // audioTransceiver.direction = 'sendonly';
const offer = await pc.createOffer(); // const offer = await pc.createOffer();
await pc.setLocalDescription(offer); // await pc.setLocalDescription(offer);
dc.send('1' + offer.sdp); // dc.send('1' + offer.sdp);
action = unpublish; // action = unpublish;
document.getElementById('sw').innerText = 'unpublish'; // document.getElementById('sw').innerText = 'unpublish';
}; // };
const unpublish = async () => { // const unpublish = async () => {
videoTransceiver.direction = 'inactive'; // videoTransceiver.direction = 'inactive';
audioTransceiver.direction = 'inactive'; // audioTransceiver.direction = 'inactive';
const offer = await pc.createOffer(); // const offer = await pc.createOffer();
await pc.setLocalDescription(offer); // await pc.setLocalDescription(offer);
dc.send('0' + offer.sdp); // dc.send('0' + offer.sdp);
action = publish; // action = publish;
document.getElementById('sw').innerText = 'publish'; // document.getElementById('sw').innerText = 'publish';
}; // };
action = unpublish; // action = unpublish;
})() })()
</script> </script>

View File

@@ -1,7 +1,6 @@
package webrtc package webrtc
import ( import (
"fmt"
"time" "time"
"github.com/pion/rtcp" "github.com/pion/rtcp"
@@ -75,7 +74,8 @@ func (puber *WebRTCPublisher) writeRTCP(track *TrackRemote) {
select { select {
case <-ticker.C: case <-ticker.C:
if rtcpErr := puber.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: uint32(track.SSRC())}}); rtcpErr != nil { if rtcpErr := puber.WriteRTCP([]rtcp.Packet{&rtcp.PictureLossIndication{MediaSSRC: uint32(track.SSRC())}}); rtcpErr != nil {
fmt.Println(rtcpErr) puber.Error("writeRTCP", zap.Error(rtcpErr))
return
} }
case <-puber.Done(): case <-puber.Done():
return return

87
subscribe.html Normal file
View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试WebRTC拉流</title>
</head>
<body>
<video id="video" width="640" height="480" autoplay>
</video>
<!-- <button id="sw" onclick="action()" type="button" style="width:100px;height:30px;display: block;">unpublish</button> -->
<pre>
<code id="remoteSdp">
</code>
</pre>
</body>
<script>
let action = () => { console.log('action not set'); };
(async () => {
const pc = new RTCPeerConnection();
pc.ontrack = (e) => {
console.log('ontrack', e);
if (e.streams.length === 0) return;
document.getElementById('video').srcObject = e.streams[0];
};
pc.oniceconnectionstatechange = () => {
console.log('oniceconnectionstatechange', pc.iceConnectionState);
};
pc.onicecandidate = (e) => {
console.log('onicecandidate', e.candidate);
};
pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });
// const dc = pc.createDataChannel('sdp');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const result = await fetch(
`/webrtc/play/live/webrtc`,
{
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'include',
redirect: 'follow',
referrerPolicy: 'no-referrer',
headers: { 'Content-Type': 'application/sdp' },
body: offer.sdp,
},
);
const remoteSdp = await result.text();
document.getElementById('remoteSdp').innerText = remoteSdp;
await pc.setRemoteDescription(
new RTCSessionDescription({ type: 'answer', sdp: remoteSdp }),
);
// dc.onmessage = async (e) => {
// await pc.setRemoteDescription(
// new RTCSessionDescription({ type: 'answer', sdp: e.data }),
// );
// };
// const publish = async () => {
// videoTransceiver.direction = 'sendonly';
// audioTransceiver.direction = 'sendonly';
// const offer = await pc.createOffer();
// await pc.setLocalDescription(offer);
// dc.send('1' + offer.sdp);
// action = unpublish;
// document.getElementById('sw').innerText = 'unpublish';
// };
// const unpublish = async () => {
// videoTransceiver.direction = 'inactive';
// audioTransceiver.direction = 'inactive';
// const offer = await pc.createOffer();
// await pc.setLocalDescription(offer);
// dc.send('0' + offer.sdp);
// action = publish;
// document.getElementById('sw').innerText = 'publish';
// };
// action = unpublish;
})()
</script>
</html>