First attempt with plyr
This commit is contained in:
parent
df821e07af
commit
0201bcd4a9
119
index.html
119
index.html
|
@ -5,14 +5,90 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/ico" href="/favicon.ico"/>
|
||||
<link href="css/video-js.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.6.7/plyr.css" />
|
||||
<link href="css/spinner.css" rel="stylesheet">
|
||||
<style>
|
||||
video, .plyr, .plyr__video-wrapper {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="js/vd.js"></script>
|
||||
<script src="https://cdn.plyr.io/3.6.7/plyr.polyfilled.js"></script>
|
||||
<script src="https://cdn.rawgit.com/video-dev/hls.js/18bb552/dist/hls.min.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script>
|
||||
customElements.define('plyr-video',
|
||||
class PlyrVideo extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.videoElement = document.createElement('video');
|
||||
this.videoElement.setAttribute('controls', 'true');
|
||||
}
|
||||
|
||||
static get observedAttributes() { return []; }
|
||||
|
||||
connectedCallback() {
|
||||
this.appendChild(this.videoElement)
|
||||
|
||||
const hls = new Hls();
|
||||
hls.loadSource(this.getAttribute('src'));
|
||||
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
|
||||
|
||||
// Transform available levels into an array of integers (height values).
|
||||
const availableQualities = hls.levels.map((l) => l.height);
|
||||
availableQualities.unshift(0);
|
||||
|
||||
// Initialize here
|
||||
new Plyr(this.videoElement, {
|
||||
quality: {
|
||||
default: 0,
|
||||
options: availableQualities,
|
||||
// this ensures Plyr to use Hls to update quality level
|
||||
forced: true,
|
||||
onChange: updateQuality,
|
||||
debug: true,
|
||||
},
|
||||
fullscreen: {
|
||||
enabled: true,
|
||||
fallback: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
hls.on(Hls.Events.LEVEL_SWITCHED, function (event, data) {
|
||||
var span = document.querySelector(".plyr__menu__container [data-plyr='quality'][value='0'] span");
|
||||
if (hls.autoLevelEnabled) {
|
||||
span.innerHTML = "Auto (" + hls.levels[data.level].height + "p)";
|
||||
} else {
|
||||
span.innerHTML = "Auto";
|
||||
}
|
||||
var x = document.querySelectorAll(".plyr__menu__container [data-plyr='settings'] span")[3];
|
||||
if (x.innerHTML.startsWith("Auto") || x.innerHTML === "0p") {
|
||||
x.innerHTML = span.innerHTML;
|
||||
}
|
||||
})
|
||||
|
||||
hls.attachMedia(this.videoElement);
|
||||
|
||||
function updateQuality(newQuality) {
|
||||
if (newQuality === 0) {
|
||||
hls.currentLevel = -1;
|
||||
} else {
|
||||
hls.levels.forEach((level, levelIndex) => {
|
||||
if (level.height === newQuality) {
|
||||
hls.currentLevel = levelIndex;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function isDarkMode(e) {
|
||||
var darkMode = JSON.parse(localStorage.getItem('darkMode'));
|
||||
|
||||
|
@ -37,30 +113,9 @@
|
|||
}
|
||||
});
|
||||
|
||||
var lastId, player;
|
||||
var lastId;
|
||||
|
||||
if (app.ports !== undefined) {
|
||||
if (app.ports.registerVideo !== undefined) {
|
||||
app.ports.registerVideo.subscribe(function(args) {
|
||||
window.scrollTo(0, 0);
|
||||
var time = vd.parseTime(args[2]) || undefined;
|
||||
|
||||
requestAnimationFrame(function() {
|
||||
if (args[0] !== lastId) {
|
||||
lastId = args[0];
|
||||
|
||||
player = vd.setup(args[0], {
|
||||
v: args[1] + "/manifest.m3u8",
|
||||
t: time,
|
||||
focus: true
|
||||
});
|
||||
} else if (time !== undefined ){
|
||||
player.currentTime(time);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (app.ports.setDarkMode !== undefined) {
|
||||
app.ports.setDarkMode.subscribe(function(arg) {
|
||||
if (arg === null) {
|
||||
|
@ -73,19 +128,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (app.ports !== undefined) {
|
||||
if (app.ports.eraseVideo !== undefined) {
|
||||
app.ports.eraseVideo.subscribe(function() {
|
||||
window.scrollTo(0, 0);
|
||||
lastId = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
||||
app.ports.darkMode.send(isDarkMode(e));
|
||||
});
|
||||
}
|
||||
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
||||
app.ports.darkMode.send(isDarkMode(e));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
20
src/Core.elm
20
src/Core.elm
|
@ -231,28 +231,18 @@ update msg model =
|
|||
_ ->
|
||||
Nothing
|
||||
|
||||
( page, cmd ) =
|
||||
page =
|
||||
case ( playlist, video ) of
|
||||
( Just p, Just v ) ->
|
||||
( Video p v Nothing
|
||||
, Ports.registerVideo ( Twitch.videoId v, "videos/" ++ p.url ++ v.url, time )
|
||||
)
|
||||
Video p v Nothing
|
||||
|
||||
( Just p, Nothing ) ->
|
||||
( Playlist p Nothing, Cmd.none )
|
||||
Playlist p Nothing
|
||||
|
||||
_ ->
|
||||
( Home Nothing, Cmd.none )
|
||||
|
||||
extraCmd =
|
||||
case page of
|
||||
Video _ _ _ ->
|
||||
Cmd.none
|
||||
|
||||
_ ->
|
||||
Ports.eraseVideo ()
|
||||
Home Nothing
|
||||
in
|
||||
( { model | page = page }, Cmd.batch [ cmd, extraCmd ] )
|
||||
( { model | page = page }, Cmd.none )
|
||||
|
||||
UrlRequested u ->
|
||||
case u of
|
||||
|
|
|
@ -381,28 +381,10 @@ videoView darkMode device zone currentDate time hover playlist video =
|
|||
, Element.alignTop
|
||||
, Element.height Element.fill
|
||||
]
|
||||
[ Keyed.el
|
||||
[ Element.width Element.fill
|
||||
, Element.height (Element.px 0)
|
||||
, Element.htmlAttribute (Html.Attributes.style "padding-top" "56.25%")
|
||||
, Element.htmlAttribute (Html.Attributes.style "position" "relative")
|
||||
]
|
||||
( video.url
|
||||
, Element.html
|
||||
(Html.video
|
||||
[ Html.Attributes.id (Twitch.videoId video)
|
||||
, Html.Attributes.class "video-js"
|
||||
, Html.Attributes.class "vjs-default-skin"
|
||||
, Html.Attributes.class "wf"
|
||||
, Html.Attributes.property "data-setup" (Encode.string "{\"fluid\": true}")
|
||||
, Html.Attributes.style "position" "absolute"
|
||||
, Html.Attributes.style "top" "0"
|
||||
, Html.Attributes.style "height" "100%"
|
||||
, Html.Attributes.controls True
|
||||
, Html.Attributes.autoplay True
|
||||
]
|
||||
[]
|
||||
)
|
||||
[ Element.html
|
||||
(Html.node "plyr-video"
|
||||
[ Html.Attributes.attribute "src" ("videos/" ++ playlist.url ++ video.url ++ "manifest.m3u8") ]
|
||||
[]
|
||||
)
|
||||
, Element.paragraph
|
||||
[ Font.size Consts.homeFontSize
|
||||
|
|
Loading…
Reference in New Issue