Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
eslotsys-game-nuxt
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
毛线
eslotsys-game-nuxt
Commits
d8f0011a
Commit
d8f0011a
authored
Jun 29, 2023
by
毛线
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
save
parent
f4a9f21d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
351 additions
and
4 deletions
+351
-4
.eslintignore
.eslintignore
+1
-0
_id.vue
pages/index/game/_id.vue
+102
-1
index.vue
pages/index/index.vue
+3
-0
plugins.js
plugins/plugins.js
+3
-3
webrtc.js
utils/webrtc.js
+242
-0
No files found.
.eslintignore
View file @
d8f0011a
webrtc.js
\ No newline at end of file
pages/index/game/_id.vue
View file @
d8f0011a
<
template
>
<div>
{{
id
}}
{{
backgroundUrl
}}
<img
:src=
"backgroundUrl | img"
alt=
""
style=
"width: 100px;"
>
<button
@
click=
"click().quit()"
>
退出游戏
</button>
<div>
<div>
按钮
</div>
<div
class=
"game-btn-block"
>
<div
v-for=
"(item, index) in btnList.filter(i => i.buttonStatus === 1)"
:key=
"index"
class=
"game-btn btn"
@
click=
"click().gameBtn(item)"
>
<div
v-if=
"item.buttonImgN"
class=
"bg"
>
<img
:src=
"item.buttonImgN | img"
alt=
""
>
</div>
<button
v-else
>
{{
item
.
buttonName
}}
{{
item
.
buttonStatus
}}
{{
item
.
buttonValue
}}
</button>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
{
WebRTCPlayer
}
from
'@/utils/webrtc'
export
default
{
data
()
{
return
{}
return
{
player
:
''
,
deviceButtonPanel
:
{},
}
},
computed
:
{
id
()
{
return
this
.
$route
.
params
.
id
},
backgroundUrl
()
{
return
this
.
deviceButtonPanel
.
backgroundUrl
},
btnList
()
{
return
this
.
deviceButtonPanel
.
keyMapping
||
[]
},
},
mounted
()
{
this
.
network
().
getData
()
this
.
network
().
isSave
()
this
.
init
().
play
()
},
methods
:
{
init
()
{
return
{
play
:
()
=>
{
if
(
!
this
.
player
)
{
const
player
=
new
WebRTCPlayer
()
player
.
onPlay
=
()
=>
this
.
doPlay
(
player
.
stream
)
player
.
onStatus
=
1
this
.
player
=
player
}
this
.
player
.
play
(
'webrtc://eslotstreaming.com/hdmi/egm8m'
)
},
}
},
network
()
{
return
{
getData
:
()
=>
{
...
...
@@ -32,6 +70,10 @@ export default {
params
,
}).
then
(({
data
})
=>
{
console
.
log
(
'getDeviceButtonPanel'
,
data
)
data
.
keyMapping
=
JSON
.
parse
(
data
.
keyMapping
)
this
.
deviceButtonPanel
=
data
const
{
keyMapping
}
=
data
console
.
log
(
'keyMapping'
,
keyMapping
)
})
},
isSave
:
()
=>
{
...
...
@@ -47,8 +89,67 @@ export default {
console
.
log
(
'isSave'
,
data
)
})
},
quit
:
()
=>
{
const
{
id
}
=
this
const
params
=
{
deviceId
:
id
,
}
this
.
$request
({
url
:
'/api/app/device/quitDevice'
,
method
:
'get'
,
params
,
}).
then
(({
data
})
=>
{
console
.
log
(
'quit'
,
data
)
this
.
$router
.
go
(
-
1
)
})
},
button
:
({
buttonValue
})
=>
{
const
{
id
}
=
this
const
params
=
{
deviceId
:
id
,
methodName
:
'click'
,
key
:
buttonValue
,
}
this
.
$request
({
url
:
'/api/game/button'
,
method
:
'get'
,
params
,
}).
then
(({
data
})
=>
{
})
},
}
},
click
()
{
return
{
quit
:
()
=>
{
this
.
network
().
quit
()
},
gameBtn
:
(
item
)
=>
{
this
.
network
().
button
(
item
)
},
}
},
},
}
</
script
>
<
style
lang=
"scss"
scoped
>
.game-btn-block
{
display
:
flex
;
.game-btn
{
width
:
80px
;
height
:
80px
;
position
:
relative
;
.bg
{
position
:
absolute
;
width
:
100%
;
height
:
100%
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
}
</
style
>
pages/index/index.vue
View file @
d8f0011a
<
template
>
<div>
<div
v-for=
"(item, index) in list"
:key=
"index"
class=
"box btn"
@
click=
"click().joinGasme(item)"
>
<div>
gameNameEn:
{{
item
.
gameNameEn
}}
</div>
<div>
assetNumber:
{{
item
.
assetNumber
}}
</div>
...
...
plugins/plugins.js
View file @
d8f0011a
import
Vue
from
'vue'
import
print
from
'print-js'
import
'xe-utils'
Vue
.
filter
(
'img'
,
function
(
value
)
{
return
`
${
process
.
env
.
img_domain
}${
value
}
`
})
utils/webrtc.js
0 → 100644
View file @
d8f0011a
export
class
WebRTCPlayer
{
constructor
()
{
const
PeerConnection
=
window
.
RTCPeerConnection
||
window
.
mozRTCPeerConnection
||
window
.
webkitRTCPeerConnection
;
if
(
!
PeerConnection
)
{
throw
"系统不支持"
;
}
try
{
this
.
pc
=
new
RTCPeerConnection
();
this
.
pc
.
onaddstream
=
(
event
)
=>
{
this
.
stream
=
event
.
stream
;
if
(
this
.
onPlay
)
{
this
.
onPlay
()
}
};
this
.
pc
.
onconnectionstatechange
=
(
event
)
=>
{
console
.
log
(
'webrtc state'
,
Date
.
now
(),
event
.
target
.
connectionState
)
if
(
this
.
onStatus
)
{
this
.
onStatus
(
event
.
target
.
connectionState
)
}
}
// this.pc.oniceconnectionstatechange =(event) => {
// console.log("webrtc ice state", Date.now(), event.target.iceConnectionState)
// if (event.target.iceConnectionState === 'disconnected') {
// if (this.onStatus) {
// this.onStatus(event.target.iceConnectionState)
// }
// }
// }
}
catch
(
e
)
{
throw
"系统不支持"
;
}
}
request
(
opts
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
opts
=
opts
||
{};
opts
=
Object
.
assign
({},
{
type
:
"POST"
,
dataType
:
"json"
,
async
:
true
// 异步请求
},
opts
);
opts
.
data
=
opts
.
data
||
{};
let
xhr
=
{};
if
(
window
.
XMLHttpRequest
)
{
// W3C标准
xhr
=
new
XMLHttpRequest
();
}
else
{
// IE标准
xhr
=
new
ActiveXObject
(
"Microsoft.XMLHTTP"
);
}
xhr
.
onreadystatechange
=
()
=>
{
if
(
xhr
.
readyState
==
4
)
{
const
status
=
xhr
.
status
;
if
(
status
>=
200
&&
status
<
300
)
{
resolve
(
JSON
.
parse
(
xhr
.
responseText
));
}
else
{
reject
(
'网络异常'
);
}
}
};
if
(
opts
.
type
==
"GET"
)
{
const
query
=
[];
for
(
const
key
in
opts
.
data
)
{
if
(
typeof
opts
.
data
[
key
]
===
"object"
)
{
opts
.
data
[
key
]
=
JSON
.
stringify
(
opts
.
data
[
key
])
}
query
.
push
(
encodeURIComponent
(
key
)
+
"="
+
encodeURIComponent
(
opts
.
data
[
key
]));
}
// 对需要传入的参数的处理
const
params
=
query
.
join
(
"&"
);
xhr
.
open
(
"GET"
,
opts
.
url
+
"?"
+
params
,
opts
.
async
);
xhr
.
send
(
null
);
}
else
if
(
opts
.
type
==
"POST"
)
{
//打开请求
xhr
.
open
(
"POST"
,
opts
.
url
,
opts
.
async
);
//POST请求设置请求头
if
(
opts
.
dataType
===
'json'
)
{
xhr
.
setRequestHeader
(
"Content-Type"
,
"application/json"
);
}
//发送请求参数
xhr
.
send
(
JSON
.
stringify
(
opts
.
data
));
}
});
}
async
play
(
url
)
{
this
.
pc
.
addTransceiver
(
"audio"
,
{
direction
:
"recvonly"
});
this
.
pc
.
addTransceiver
(
"video"
,
{
direction
:
"recvonly"
});
const
offer
=
await
this
.
pc
.
createOffer
({
offerToReceiveAudio
:
1
,
offerToReceiveVideo
:
1
});
await
this
.
pc
.
setLocalDescription
(
offer
);
if
(
/^webrtc:/ig
.
test
(
url
))
{
const
conf
=
this
.
prepareUrl
(
url
);
const
apiUrl
=
conf
.
apiUrl
;
const
streamUrl
=
conf
.
streamUrl
;
const
data
=
{
api
:
apiUrl
,
streamurl
:
streamUrl
,
clientip
:
null
,
sdp
:
offer
.
sdp
};
const
res
=
await
this
.
request
({
url
:
apiUrl
,
data
:
data
,
});
if
(
res
.
code
)
{
throw
'网络异常'
;
}
console
.
log
(
'webrtc sdp'
,
res
.
sdp
)
this
.
pc
.
setRemoteDescription
(
new
RTCSessionDescription
({
type
:
'answer'
,
sdp
:
res
.
sdp
})
);
}
}
close
()
{
this
.
pc
.
close
();
}
// 格式化trmp url
parseRtmpUrl
(
rtmpUrl
)
{
const
a
=
document
.
createElement
(
"a"
);
a
.
href
=
rtmpUrl
.
replace
(
"rtmp://"
,
"http://"
).
replace
(
"webrtc://"
,
"http://"
).
replace
(
"rtc://"
,
"http://"
);
const
vhost
=
a
.
hostname
;
let
app
=
a
.
pathname
.
substr
(
1
,
a
.
pathname
.
lastIndexOf
(
"/"
)
-
1
);
const
stream
=
a
.
pathname
.
substr
(
a
.
pathname
.
lastIndexOf
(
"/"
)
+
1
);
// parse the vhost in the params of app, that srs supports.
app
=
app
.
replace
(
"...vhost..."
,
"?vhost="
);
if
(
app
.
indexOf
(
"?"
)
>=
0
)
{
const
params
=
app
.
substr
(
app
.
indexOf
(
"?"
));
app
=
app
.
substr
(
0
,
app
.
indexOf
(
"?"
));
if
(
params
.
indexOf
(
"vhost="
)
>
0
)
{
vhost
=
params
.
substr
(
params
.
indexOf
(
"vhost="
)
+
"vhost="
.
length
);
if
(
vhost
.
indexOf
(
"&"
)
>
0
)
{
vhost
=
vhost
.
substr
(
0
,
vhost
.
indexOf
(
"&"
));
}
}
}
// when vhost equals to server, and server is ip,
// the vhost is __defaultVhost__
if
(
a
.
hostname
===
vhost
)
{
const
re
=
/^
(\d
+
)\.(\d
+
)\.(\d
+
)\.(\d
+
)
$/
;
if
(
re
.
test
(
a
.
hostname
))
{
vhost
=
"__defaultVhost__"
;
}
}
// parse the schema
let
schema
=
"rtmp"
;
if
(
rtmpUrl
.
indexOf
(
"://"
)
>
0
)
{
schema
=
rtmpUrl
.
substr
(
0
,
rtmpUrl
.
indexOf
(
"://"
));
}
let
port
=
a
.
port
;
if
(
!
port
)
{
if
(
schema
===
'http'
)
{
port
=
80
;
}
else
if
(
schema
===
'https'
)
{
port
=
443
;
}
else
if
(
schema
===
'rtmp'
)
{
port
=
1935
;
}
}
const
ret
=
{
url
:
rtmpUrl
,
schema
:
schema
,
server
:
a
.
hostname
,
port
:
port
,
vhost
:
vhost
,
app
:
app
,
stream
:
stream
};
let
queryStr
=
a
.
search
;
ret
.
user_query
=
{};
if
(
queryStr
.
length
>
0
)
{
// split again for angularjs.
if
(
queryStr
.
indexOf
(
"?"
)
>=
0
)
{
queryStr
=
queryStr
.
split
(
"?"
)[
1
];
}
const
queries
=
queryStr
.
split
(
"&"
);
for
(
const
i
=
0
;
i
<
queries
.
length
;
i
++
)
{
const
elem
=
queries
[
i
];
const
query
=
elem
.
split
(
"="
);
ret
[
query
[
0
]]
=
query
[
1
];
ret
.
user_query
[
query
[
0
]]
=
query
[
1
];
}
// alias domain for vhost.
if
(
ret
.
domain
)
{
ret
.
vhost
=
ret
.
domain
;
}
}
// For webrtc API, we use 443 if page is https, or schema specified it.
if
(
!
ret
.
port
)
{
if
(
schema
===
'webrtc'
||
schema
===
'rtc'
)
{
if
(
ret
.
user_query
.
schema
===
'https'
)
{
ret
.
port
=
443
;
}
else
if
(
window
.
location
.
href
.
indexOf
(
'https://'
)
===
0
)
{
ret
.
port
=
443
;
}
else
{
// For WebRTC, SRS use 1985 as default API port.
ret
.
port
=
1985
;
}
}
}
return
ret
;
};
// 生成RTC API url
prepareUrl
(
url
)
{
let
apiUrl
,
streamUrl
;
const
urlObject
=
this
.
parseRtmpUrl
(
url
);
let
schema
=
urlObject
.
user_query
.
schema
;
schema
=
schema
?
schema
+
':'
:
window
.
location
.
protocol
;
let
port
=
urlObject
.
port
||
1985
;
if
(
schema
===
'https:'
)
{
port
=
urlObject
.
port
||
443
;
}
if
(
schema
===
'file:'
)
{
schema
=
'http:'
;
}
let
api
=
urlObject
.
user_query
.
play
||
'/rtc/v1/play/'
;
if
(
api
.
lastIndexOf
(
'/'
)
!==
api
.
length
-
1
)
{
api
+=
'/'
;
}
apiUrl
=
schema
+
'//'
+
urlObject
.
server
+
/* ':' + port +*/
api
;
for
(
const
key
in
urlObject
.
user_query
)
{
if
(
key
!==
'api'
&&
key
!==
'play'
)
{
apiUrl
+=
'&'
+
key
+
'='
+
urlObject
.
user_query
[
key
];
}
}
// Replace /rtc/v1/play/&k=v to /rtc/v1/play/?k=v
apiUrl
=
apiUrl
.
replace
(
api
+
'&'
,
api
+
'?'
);
streamUrl
=
urlObject
.
url
;
return
{
apiUrl
:
apiUrl
,
streamUrl
:
streamUrl
,
schema
:
schema
,
urlObject
:
urlObject
,
port
:
port
};
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment