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
c24d782e
Commit
c24d782e
authored
Jul 11, 2023
by
毛线
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
直播支持https
parent
5f2e228b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
363 additions
and
1 deletion
+363
-1
.eslintignore
.eslintignore
+1
-0
nuxt.config.js
nuxt.config.js
+0
-1
WebRTCPlayer.vue
pages/index/game/components/WebRTCPlayer.vue
+1
-0
jswebrtc.min.js
utils/jswebrtc.min.js
+361
-0
No files found.
.eslintignore
View file @
c24d782e
webrtc.js
webrtc.js
jswebrtc.min.js
WebRTCPlayer.vue
WebRTCPlayer.vue
\ No newline at end of file
nuxt.config.js
View file @
c24d782e
...
@@ -21,7 +21,6 @@ export default {
...
@@ -21,7 +21,6 @@ export default {
{
rel
:
'icon'
,
type
:
'image/x-icon'
,
href
:
'/favicon.ico'
},
{
rel
:
'icon'
,
type
:
'image/x-icon'
,
href
:
'/favicon.ico'
},
],
],
script
:
[
script
:
[
{
src
:
`https://kuawai.s3.ap-east-1.amazonaws.com/temp/jswebrtc.min.js`
,
ssr
:
false
},
],
],
},
},
env
:
process
.
env
,
env
:
process
.
env
,
...
...
pages/index/game/components/WebRTCPlayer.vue
View file @
c24d782e
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
JSWebrtc
from
'@/utils/jswebrtc.min.js'
import
{
mapState
}
from
'vuex'
import
{
mapState
}
from
'vuex'
export
default
{
export
default
{
name
:
"WebRTCPlayer"
,
name
:
"WebRTCPlayer"
,
...
...
utils/jswebrtc.min.js
0 → 100644
View file @
c24d782e
var
JSWebrtc
=
{
Player
:
null
,
VideoElement
:
null
,
CreateVideoElements
:
function
()
{
var
elements
=
document
.
querySelectorAll
(
".jswebrtc"
);
for
(
var
i
=
0
;
i
<
elements
.
length
;
i
++
)
{
new
JSWebrtc
.
VideoElement
(
elements
[
i
])
}
},
FillQuery
:
function
(
query_string
,
obj
)
{
obj
.
user_query
=
{};
if
(
query_string
.
length
==
0
)
return
;
if
(
query_string
.
indexOf
(
"?"
)
>=
0
)
query_string
=
query_string
.
split
(
"?"
)[
1
];
var
queries
=
query_string
.
split
(
"&"
);
for
(
var
i
=
0
;
i
<
queries
.
length
;
i
++
)
{
var
query
=
queries
[
i
].
split
(
"="
);
obj
[
query
[
0
]]
=
query
[
1
];
obj
.
user_query
[
query
[
0
]]
=
query
[
1
]
}
if
(
obj
.
domain
)
obj
.
vhost
=
obj
.
domain
},
ParseUrl
:
function
(
rtmp_url
)
{
var
a
=
document
.
createElement
(
"a"
);
a
.
href
=
rtmp_url
.
replace
(
"rtmp://"
,
"https://"
).
replace
(
"webrtc://"
,
"https://"
).
replace
(
"rtc://"
,
"https://"
);
var
vhost
=
a
.
hostname
;
var
app
=
a
.
pathname
.
substr
(
1
,
a
.
pathname
.
lastIndexOf
(
"/"
)
-
1
);
var
stream
=
a
.
pathname
.
substr
(
a
.
pathname
.
lastIndexOf
(
"/"
)
+
1
);
app
=
app
.
replace
(
"...vhost..."
,
"?vhost="
);
if
(
app
.
indexOf
(
"?"
)
>=
0
)
{
var
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
(
"&"
))
}
}
}
if
(
a
.
hostname
==
vhost
)
{
var
re
=
/^
(\d
+
)\.(\d
+
)\.(\d
+
)\.(\d
+
)
$/
;
if
(
re
.
test
(
a
.
hostname
))
vhost
=
"__defaultVhost__"
}
var
schema
=
"rtmp"
;
if
(
rtmp_url
.
indexOf
(
"://"
)
>
0
)
schema
=
rtmp_url
.
substr
(
0
,
rtmp_url
.
indexOf
(
"://"
));
var
port
=
a
.
port
;
if
(
!
port
)
{
if
(
schema
===
"http"
)
{
port
=
80
}
else
if
(
schema
===
"https"
)
{
port
=
443
}
else
if
(
schema
===
"rtmp"
)
{
port
=
1935
}
else
if
(
schema
===
"webrtc"
||
schema
===
"rtc"
)
{
port
=
443
}
}
var
ret
=
{
url
:
rtmp_url
,
schema
:
schema
,
server
:
a
.
hostname
,
port
:
port
,
vhost
:
vhost
,
app
:
app
,
stream
:
stream
};
JSWebrtc
.
FillQuery
(
a
.
search
,
ret
);
return
ret
},
HttpPost
:
function
(
url
,
data
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
xhr
=
new
XMLHttpRequest
;
xhr
.
onreadystatechange
=
function
()
{
if
(
xhr
.
readyState
===
4
&&
(
xhr
.
status
>=
200
&&
xhr
.
status
<
300
))
{
var
respone
=
JSON
.
parse
(
xhr
.
responseText
);
xhr
.
onreadystatechange
=
new
Function
;
xhr
=
null
;
resolve
(
respone
)
}
}
;
xhr
.
open
(
"POST"
,
url
,
true
);
xhr
.
timeout
=
5
e3
;
xhr
.
responseType
=
"text"
;
xhr
.
setRequestHeader
(
"Content-Type"
,
"application/json"
);
xhr
.
send
(
data
)
}
)
}
};
if
(
document
.
readyState
===
"complete"
)
{
JSWebrtc
.
CreateVideoElements
()
}
else
{
document
.
addEventListener
(
"DOMContentLoaded"
,
JSWebrtc
.
CreateVideoElements
)
}
JSWebrtc
.
VideoElement
=
function
()
{
"use strict"
;
var
VideoElement
=
function
(
element
)
{
var
url
=
element
.
dataset
.
url
;
if
(
!
url
)
{
throw
"VideoElement has no `data-url` attribute"
}
var
addStyles
=
function
(
element
,
styles
)
{
for
(
var
name
in
styles
)
{
element
.
style
[
name
]
=
styles
[
name
]
}
};
this
.
container
=
element
;
addStyles
(
this
.
container
,
{
display
:
"inline-block"
,
position
:
"relative"
,
minWidth
:
"80px"
,
minHeight
:
"80px"
});
this
.
video
=
document
.
createElement
(
"video"
);
this
.
video
.
width
=
960
;
this
.
video
.
height
=
540
;
addStyles
(
this
.
video
,
{
display
:
"block"
,
width
:
"100%"
});
this
.
container
.
appendChild
(
this
.
video
);
this
.
playButton
=
document
.
createElement
(
"div"
);
this
.
playButton
.
innerHTML
=
VideoElement
.
PLAY_BUTTON
;
addStyles
(
this
.
playButton
,
{
zIndex
:
2
,
position
:
"absolute"
,
top
:
"0"
,
bottom
:
"0"
,
left
:
"0"
,
right
:
"0"
,
maxWidth
:
"75px"
,
maxHeight
:
"75px"
,
margin
:
"auto"
,
opacity
:
"0.7"
,
cursor
:
"pointer"
});
this
.
container
.
appendChild
(
this
.
playButton
);
var
options
=
{
video
:
this
.
video
};
for
(
var
option
in
element
.
dataset
)
{
try
{
options
[
option
]
=
JSON
.
parse
(
element
.
dataset
[
option
])
}
catch
(
err
)
{
options
[
option
]
=
element
.
dataset
[
option
]
}
}
this
.
player
=
new
JSWebrtc
.
Player
(
url
,
options
);
element
.
playerInstance
=
this
.
player
;
if
(
options
.
poster
&&
!
options
.
autoplay
)
{
options
.
decodeFirstFrame
=
false
;
this
.
poster
=
new
Image
;
this
.
poster
.
src
=
options
.
poster
;
this
.
poster
.
addEventListener
(
"load"
,
this
.
posterLoaded
);
addStyles
(
this
.
poster
,
{
display
:
"block"
,
zIndex
:
1
,
position
:
"absolute"
,
top
:
0
,
left
:
0
,
bottom
:
0
,
right
:
0
});
this
.
container
.
appendChild
(
this
.
poster
)
}
if
(
!
this
.
player
.
options
.
streaming
)
{
this
.
container
.
addEventListener
(
"click"
,
this
.
onClick
.
bind
(
this
))
}
if
(
options
.
autoplay
)
{
this
.
playButton
.
style
.
display
=
"none"
}
if
(
this
.
player
.
audioOut
&&
!
this
.
player
.
audioOut
.
unlocked
)
{
var
unlockAudioElement
=
this
.
container
;
if
(
options
.
autoplay
)
{
this
.
unmuteButton
=
document
.
createElement
(
"div"
);
this
.
unmuteButton
.
innerHTML
=
VideoElement
.
UNMUTE_BUTTON
;
addStyles
(
this
.
unmuteButton
,
{
zIndex
:
2
,
position
:
"absolute"
,
bottom
:
"10px"
,
right
:
"20px"
,
width
:
"75px"
,
height
:
"75px"
,
margin
:
"auto"
,
opacity
:
"0.7"
,
cursor
:
"pointer"
});
this
.
container
.
appendChild
(
this
.
unmuteButton
);
unlockAudioElement
=
this
.
unmuteButton
}
this
.
unlockAudioBound
=
this
.
onUnlockAudio
.
bind
(
this
,
unlockAudioElement
);
unlockAudioElement
.
addEventListener
(
"touchstart"
,
this
.
unlockAudioBound
,
false
);
unlockAudioElement
.
addEventListener
(
"click"
,
this
.
unlockAudioBound
,
true
)
}
};
VideoElement
.
prototype
.
onUnlockAudio
=
function
(
element
,
ev
)
{
if
(
this
.
unmuteButton
)
{
ev
.
preventDefault
();
ev
.
stopPropagation
()
}
this
.
player
.
audioOut
.
unlock
(
function
()
{
if
(
this
.
unmuteButton
)
{
this
.
unmuteButton
.
style
.
display
=
"none"
}
element
.
removeEventListener
(
"touchstart"
,
this
.
unlockAudioBound
);
element
.
removeEventListener
(
"click"
,
this
.
unlockAudioBound
)
}
.
bind
(
this
))
}
;
VideoElement
.
prototype
.
onClick
=
function
(
ev
)
{
if
(
this
.
player
.
isPlaying
)
{
this
.
player
.
pause
();
this
.
playButton
.
style
.
display
=
"block"
}
else
{
this
.
player
.
play
();
this
.
playButton
.
style
.
display
=
"none"
;
if
(
this
.
poster
)
{
this
.
poster
.
style
.
display
=
"none"
}
}
}
;
VideoElement
.
PLAY_BUTTON
=
'<svg style="max-width: 75px; max-height: 75px;" '
+
'viewBox="0 0 200 200" alt="Play video">'
+
'<circle cx="100" cy="100" r="90" fill="none" '
+
'stroke-width="15" stroke="#fff"/>'
+
'<polygon points="70, 55 70, 145 145, 100" fill="#fff"/>'
+
"</svg>"
;
VideoElement
.
UNMUTE_BUTTON
=
'<svg style="max-width: 75px; max-height: 75px;" viewBox="0 0 75 75">'
+
'<polygon class="audio-speaker" stroke="none" fill="#fff" '
+
'points="39,13 22,28 6,28 6,47 21,47 39,62 39,13"/>'
+
'<g stroke="#fff" stroke-width="5">'
+
'<path d="M 49,50 69,26"/>'
+
'<path d="M 69,50 49,26"/>'
+
"</g>"
+
"</svg>"
;
return
VideoElement
}();
JSWebrtc
.
Player
=
function
()
{
"use strict"
;
var
Player
=
function
(
url
,
options
)
{
this
.
options
=
options
||
{};
if
(
!
url
.
match
(
/^webrtc
?
:
\/\/
/
))
{
throw
"JSWebrtc just work with webrtc"
}
if
(
!
this
.
options
.
video
)
{
throw
"VideoElement is null"
}
this
.
urlParams
=
JSWebrtc
.
ParseUrl
(
url
);
this
.
pc
=
null
;
this
.
autoplay
=
!!
options
.
autoplay
||
false
;
this
.
paused
=
true
;
if
(
this
.
autoplay
)
this
.
options
.
video
.
muted
=
true
;
this
.
startLoading
()
};
Player
.
prototype
.
startLoading
=
function
()
{
var
_self
=
this
;
if
(
_self
.
pc
)
{
_self
.
pc
.
close
()
}
_self
.
pc
=
new
RTCPeerConnection
(
null
);
_self
.
pc
.
ontrack
=
function
(
event
)
{
_self
.
options
.
video
[
"srcObject"
]
=
event
.
streams
[
0
]
}
;
_self
.
pc
.
addTransceiver
(
"audio"
,
{
direction
:
"recvonly"
});
_self
.
pc
.
addTransceiver
(
"video"
,
{
direction
:
"recvonly"
});
_self
.
pc
.
createOffer
().
then
(
function
(
offer
)
{
return
_self
.
pc
.
setLocalDescription
(
offer
).
then
(
function
()
{
return
offer
})
}).
then
(
function
(
offer
)
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
var
port
=
_self
.
urlParams
.
port
||
443
;
var
api
=
_self
.
urlParams
.
user_query
.
play
||
"/rtc/v1/play/"
;
if
(
api
.
lastIndexOf
(
"/"
)
!=
api
.
length
-
1
)
{
api
+=
"/"
}
var
url
=
"https://"
+
_self
.
urlParams
.
server
+
":"
+
port
+
api
;
for
(
var
key
in
_self
.
urlParams
.
user_query
)
{
if
(
key
!=
"api"
&&
key
!=
"play"
)
{
url
+=
"&"
+
key
+
"="
+
_self
.
urlParams
.
user_query
[
key
]
}
}
var
data
=
{
api
:
url
,
streamurl
:
_self
.
urlParams
.
url
,
clientip
:
null
,
sdp
:
offer
.
sdp
};
console
.
log
(
"offer: "
+
JSON
.
stringify
(
data
));
JSWebrtc
.
HttpPost
(
url
,
JSON
.
stringify
(
data
)).
then
(
function
(
res
)
{
console
.
log
(
"answer: "
+
JSON
.
stringify
(
res
));
resolve
(
res
.
sdp
)
},
function
(
rej
)
{
reject
(
rej
)
})
}
)
}).
then
(
function
(
answer
)
{
return
_self
.
pc
.
setRemoteDescription
(
new
RTCSessionDescription
({
type
:
"answer"
,
sdp
:
answer
}))
}).
catch
(
function
(
reason
)
{
throw
reason
});
if
(
this
.
autoplay
)
{
this
.
play
()
}
}
;
Player
.
prototype
.
play
=
function
(
ev
)
{
if
(
this
.
animationId
)
{
return
}
this
.
animationId
=
requestAnimationFrame
(
this
.
update
.
bind
(
this
));
this
.
paused
=
false
}
;
Player
.
prototype
.
pause
=
function
(
ev
)
{
if
(
this
.
paused
)
{
return
}
cancelAnimationFrame
(
this
.
animationId
);
this
.
animationId
=
null
;
this
.
isPlaying
=
false
;
this
.
paused
=
true
;
this
.
options
.
video
.
pause
();
if
(
this
.
options
.
onPause
)
{
this
.
options
.
onPause
(
this
)
}
}
;
Player
.
prototype
.
stop
=
function
(
ev
)
{
this
.
pause
()
}
;
Player
.
prototype
.
destroy
=
function
()
{
this
.
pause
();
this
.
pc
&&
this
.
pc
.
close
()
&&
this
.
pc
.
destroy
();
this
.
audioOut
&&
this
.
audioOut
.
destroy
()
}
;
Player
.
prototype
.
update
=
function
()
{
this
.
animationId
=
requestAnimationFrame
(
this
.
update
.
bind
(
this
));
if
(
this
.
options
.
video
.
readyState
<
4
)
{
return
}
if
(
!
this
.
isPlaying
)
{
this
.
isPlaying
=
true
;
this
.
options
.
video
.
play
();
if
(
this
.
options
.
onPlay
)
{
this
.
options
.
onPlay
(
this
)
}
}
}
;
return
Player
}();
export
default
JSWebrtc
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