|
@@ -1,39 +1,153 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div id="app">
|
|
<div id="app">
|
|
|
- <Home />
|
|
|
|
|
|
|
+ <template v-if="isLogin">
|
|
|
|
|
+ <template v-if="!showLoading">
|
|
|
|
|
+ <video id="v2" autoplay playsinline muted></video>
|
|
|
|
|
+ <div class="marke"></div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <Loading v-else />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <Login v-else :err="error" @loginBack="login" />
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
-import Home from './page/index'
|
|
|
|
|
|
|
+const { io } = require("socket.io-client");
|
|
|
|
|
+import Login from "@/components/login";
|
|
|
|
|
+import Loading from "@/components/loading";
|
|
|
export default {
|
|
export default {
|
|
|
- name: 'App',
|
|
|
|
|
- components: {
|
|
|
|
|
- Home,
|
|
|
|
|
|
|
+ components: { Login, Loading },
|
|
|
|
|
+ data() {
|
|
|
|
|
+ return {
|
|
|
|
|
+ socket: null,
|
|
|
|
|
+ HOST: "wss://car.caner.top",
|
|
|
|
|
+ Peer: null,
|
|
|
|
|
+ isLogin: false,
|
|
|
|
|
+ error: "",
|
|
|
|
|
+ remoteVideo: null,
|
|
|
|
|
+ showLoading: true,
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
-}
|
|
|
|
|
|
|
+ methods: {
|
|
|
|
|
+ intSoketRtc(host) {
|
|
|
|
|
+ // int socket
|
|
|
|
|
+ this.socket = io(host, {
|
|
|
|
|
+ autoConnect: false,
|
|
|
|
|
+ transports: ["websocket"],
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // socket
|
|
|
|
|
+ this.socket.on("connect", () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ console.log("连接成功", this.socket.auth);
|
|
|
|
|
+ this.isLogin = true;
|
|
|
|
|
+ // init webrtc
|
|
|
|
|
+ this.Peer = new RTCPeerConnection({
|
|
|
|
|
+ bundlePolicy: "max-bundle",
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // listen state
|
|
|
|
|
+ this.Peer.onicegatheringstatechange = () => {
|
|
|
|
|
+ console.log("GatheringState: ", this.Peer.iceGatheringState);
|
|
|
|
|
+ if (this.Peer.iceGatheringState === "complete") {
|
|
|
|
|
+ const answer = this.Peer.localDescription;
|
|
|
|
|
+ this.socket.emit("msg", answer);
|
|
|
|
|
+ this.showLoading = false
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // listen track
|
|
|
|
|
+ this.Peer.ontrack = (evt) => {
|
|
|
|
|
+ console.log("track", evt.streams[0]);
|
|
|
|
|
+ this.remoteVideo = document.getElementById("v2");
|
|
|
|
|
+ this.remoteVideo.srcObject = evt.streams[0];
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ this.socket.disconnect();
|
|
|
|
|
+ this.isLogin = false;
|
|
|
|
|
+ alert("不支持Webrtc");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.socket.on("msg", async (data) => {
|
|
|
|
|
+ console.log(data);
|
|
|
|
|
+ if (data.type === "offer") {
|
|
|
|
|
+ await this.Peer.setRemoteDescription(data);
|
|
|
|
|
+ const answer = await this.Peer.createAnswer();
|
|
|
|
|
+ await this.Peer.setLocalDescription(answer);
|
|
|
|
|
+ } else if (data.type === "power") {
|
|
|
|
|
+ console.log("电量");
|
|
|
|
|
+ } else if (data.type === "signal") {
|
|
|
|
|
+ console.log("4G信号");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.socket.on("joined", async () =>
|
|
|
|
|
+ this.socket.emit("msg", { type: "startRTC" })
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ this.socket.on("leaved", () => this.close("车端断开"));
|
|
|
|
|
+
|
|
|
|
|
+ this.socket.on("connect_error", (err) => this.close(err));
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ login(data) {
|
|
|
|
|
+ // 设置登录头
|
|
|
|
|
+ if (this.socket) {
|
|
|
|
|
+ this.socket.auth = {
|
|
|
|
|
+ roomID: data.roomID,
|
|
|
|
|
+ name: data.name,
|
|
|
|
|
+ };
|
|
|
|
|
+ this.socket.connect();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.error = "服务器连接失败";
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ close(err) {
|
|
|
|
|
+ if (this.Peer) this.Peer.close();
|
|
|
|
|
+ if (this.remoteVideo) this.remoteVideo.srcObject = null;
|
|
|
|
|
+ this.socket.disconnect();
|
|
|
|
|
+ this.isLogin = false;
|
|
|
|
|
+ this.showLoading = false;
|
|
|
|
|
+ this.error = err || "";
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ mounted() {
|
|
|
|
|
+ this.intSoketRtc(this.HOST);
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style>
|
|
<style>
|
|
|
|
|
+video,
|
|
|
|
|
+#app,
|
|
|
html,
|
|
html,
|
|
|
body {
|
|
body {
|
|
|
margin: 0;
|
|
margin: 0;
|
|
|
padding: 0;
|
|
padding: 0;
|
|
|
user-select: none;
|
|
user-select: none;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
}
|
|
}
|
|
|
-#app {
|
|
|
|
|
- font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
|
|
|
- -webkit-font-smoothing: antialiased;
|
|
|
|
|
- -moz-osx-font-smoothing: grayscale;
|
|
|
|
|
- text-align: center;
|
|
|
|
|
- color: #2c3e50;
|
|
|
|
|
- user-select: none;
|
|
|
|
|
|
|
+
|
|
|
|
|
+video {
|
|
|
|
|
+ background: none;
|
|
|
|
|
+ object-fit: fill;
|
|
|
|
|
+ font-size: 0;
|
|
|
}
|
|
}
|
|
|
-/*去除下标*/
|
|
|
|
|
-.amap-logo{
|
|
|
|
|
-display: none!important;
|
|
|
|
|
|
|
+.marke {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ height: 30px;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.3);
|
|
|
}
|
|
}
|
|
|
-.amap-copyright{
|
|
|
|
|
-opacity:0;
|
|
|
|
|
|
|
+/* 隐藏滚动条 */
|
|
|
|
|
+::-webkit-scrollbar {
|
|
|
|
|
+ width: 0 !important;
|
|
|
|
|
+ display: none;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|