javascript - 如何在 html 中制作像 mx player 这样的视频播放器?
问题描述
我一直在开发一个以 Netflix 为主题的 HTML 视频播放器,我想知道是否有一种方法可以将它变成像 max player 这样的视频播放器,在那里你可以播放任何视频,而不是你编码到 HTML 中的视频。..................................................... ..................................................... ..................................................... ..................................................... ..
代码:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Netflix video player</title>
<link rel="stylesheet" href="https://cdnjs.cloudlflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="c-video">
<video class="video" src="video.mp4"></video>
<div class="controls">
<div class="red-bar">
<!--
inputs are self-closing tags. You don't need a closing tag for it!
Self-closing tags are single tagged elements - you only need to
add a slash before '>', like so: <input />
-->
<input class="red-juice" type="range" min="1" max="100" step="1" value="1" />
</div>
</div>
<div class="buttons">
<button id="play-pause"></button>
</div>
<div class="title"></div>
<div class="goback">
<button class="back" onclick="goBack()"></button>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS:
html,body {
margin:0;
padding:0;
}
.container {
display: flex;
background-color: #000000;
justify-content: center;
align-items: center;
height: 100vh;
}
.video {
width: 100%;
}
.c-video {
position: fixed;
width: 100%;
height: 100;
position: relative;
overflow: hidden;
}
.c-video:hover .title {
transform: translateY(0);
}
.c-video:hover .controls {
transform: translateY(0);
}
.c-video:hover .buttons {
top: 50%;
left: 50%;
transform: translate(240%, -50%);
}
.title {
display: flex;
position: absolute;
top: 0;
height: 120px;
width: 100%;
flex-wrap: wrap;
background-image: linear-gradient(rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.01));
transform: translateY(-100%);
transition: all .2s;
}
.controls {
display: flex;
position: absolute;
bottom: 0;
height: 70px;
width: 100%;
flex-wrap: wrap;
background-image: linear-gradient(rgba(0, 0, 0, 0.01), rgba(0, 0, 0, 0.9));
transform: translateY(100%);
transition: all .2s;
}
.c-video:hover .back {
transform: translate(20%, 0);
}
.back {
position: absolute;
background: none;
outline: 0;
border: 0;
top: 5%;
cursor: pointer;
transform: translate(-200000%, 0);
}
.back::before {
content: "\f060";
font-weight: 900;
font-family: "Font Awesome 5 Free";
display: inline-block;
font-size: 200%;
color: #ffff;
}
.buttons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-99999%, -50%);
}
.buttons button {
background: none;
height: 45px;
border: none;
outline: 0;
cursor: pointer;
transform: translate(-320%, 50%);
}
.buttons button:before {
content: "\f04b";
font-weight: 900;
font-family: "Font Awesome 5 Free";
display: inline-block;
font-size: 300%;
color: #ffff;
-webkit-font-smoothing: antialiased;
}
.buttons button.play:before {
content: "\f04b";
font-weight: 900;
font-family: 'Font Awesome 5 Free';
}
.buttons button.pause:before {
content: "\f04c";
font-weight: 900;
font-family: 'Font Awesome 5 Free';
}
/* Progress bar container */
.red-bar {
height: 2px;
margin-top: 15px;
margin-bottom: -15px;
background-color: rgba(0, 0, 0, 0.4);
margin-left: 10px;
margin-right: 10px;
width: 100%;
}
/* This represents the progress bar */
.red-juice {
position: relative;
width: 100%;
height: 2px;
/* thumbHeight + (2 x thumbBorderWidth)*/
background-image: linear-gradient(to right, red 1%, rgba(0, 0, 0, 0.4) 1%);
-webkit-appearance: none;
/*remove the line*/
outline: none;
top: -12px;
margin-left: 1px;
margin-right: 100px;
}
.red-juice::-webkit-slider-runnable-track {
-webkit-appearance: none;
height: 20px;
}
.red-juice::-webkit-slider-thumb {
-webkit-appearance: none;
background: red;
/*thumbColor*/
width: 15px;
/* thumbHeight + (2 x thumbBorderWidth)*/
height: 15px;
/* thumbHeight + (2 x thumbBorderWidth)*/
border-radius: 100%;
margin-top: 1px;
/* -[thumbHeight + (2 x thumbBorderWidth) - trackHeight]/2*/
cursor: pointer;
border: 0px solid #fff;
/*border-width should be equal to thumbBorderWidth if you want same border width across all browsers and border-color should match the background*/
transition: 0.3s;
}
Javascript:
var video = document.querySelector(".video");
var juice = document.querySelector(".red-juice");
var btn = document.getElementById("play-pause");
function togglePlayPause() {
if (video.paused) {
btn.className = 'pause';
video.play();
} else {
btn.className = 'play';
video.pause();
}
}
btn.onclick = function(params) {
//video.fastSeek(570); // 9:30
// video.currentTime = 570; //test
togglePlayPause();
}
video.addEventListener('timeupdate', function() {
if (video.ended) {
btn.className = "play";
// At the end of the movie, reset the position to the start and pause the playback.
video.currentTime = 0;
togglePlayPause();
}
});
function slidingProgress() {
// this.value will not work here, since it points to the global window obj
// so I'm using juice.value instead
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#Function_context
juice.style.background = 'linear-gradient(to right, red ' + juice.value * 100 / juice.max + '%, rgba(0, 0, 0, 0.4) ' + juice.value + '%, rgba(0, 0, 0, 0.4) 100%)'
}
video.addEventListener('timeupdate', () => {
juice.value = video.currentTime / video.duration * juice.max
slidingProgress() // Call your function here to update .red-juice
})
juice.addEventListener('change', () => {
video.currentTime = video.duration * juice.value / juice.max
})
// And finally assign it to juice.oninput
juice.oninput = slidingProgress;
// you're not specifying any events to listen to here, so it wouldn't work
// juice.addEventListener(slidingProgress);
function goBack() {
window.history.back();
}
解决方案
推荐阅读
- sql - 如何在 Oracle 中转置?
- node.js - AWS Lambda:在 lambda 终止(超时)之前调用方法
- java - 为什么在创建新的 java 类时,自定义向导不显示?
- wordpress - 如何从主题函数文件中删除gutenberg_render_title_tag?
- python - python加载A.so文件,其某些函数在B.so文件中定义
- html - 如何在悬停时显示跨度,然后在未悬停时不隐藏?
- github - Github 博客图片上传失败(Markdown 路径)
- c# - 为什么'if'会停止音乐并且不允许我在其中播放任何新音乐?以及如何使它工作?
- r - dplyr::mutate() -- 在 tibble 嵌套列表中,如何忽略 NULL 嵌套列表?
- python - Streamlit、Flask、Fastapi:如何将压缩文件上传到我的网络应用程序并使其可下载?