做个家用版本的家庭影院,通过这个服务器可以给电脑,平板,手机等设备提供直接播放电影的作用,通过离线下载电影放入目录里就是就可以给全家提供电影播放了,通过浏览器就是可以访问电脑里面的视频,实现简单的家庭版本服务了。
一、优化后的前端代码
1.0最终代码:【前端以这个为主;后端不变】
解决滚动条不能滚动的问题,本次带有一个滚动条,可以滚动播放列表资源;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#container {
display: flex;
flex-direction: row;
height: 50vh; /* 设置容器高度为视窗高度 */
}
/* 视频播放器样式 */
/*#videoPlayer {*/
/* display: flex;*/
/* flex-direction: row;*/
/*}*/
#video {
flex: 1;
}
/* 播放列表样式 */
.playlist {
list-style: none;
padding: 0;
width: 200px;
margin-left: 20px;
overflow-y: auto; /* 当列表超过容器高度时显示滚动条 */
height: 100%; /* 设置播放列表高度为容器高度 */
}
.playlist-item {
cursor: pointer;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: 10px;
}
.playlist-item:last-child {
margin-bottom: 0;
}
.playlist-item.active {
background-color: #f5f5f5;
}
li{
display: block;
}
</style>
</head>
<body>
<div id="container">
<!-- <video id="video" width="420" height="340" controls="controls" src="http://10.72.1.241:8080/GetFile/a1.mp4"-->
<video id="video" width="420" height="340" controls="controls" src="http://10.72.1.241:8080/GetFile/a1.mp4"
type="video/ogg"></video></br>
<ul id="playlist" class="playlist">
{{range $index,$v := .names}}
<li class="playlist-item" onclick="changeVideo('{{$v }}', '{{$v }}')">{{$v }}</li><br>
<!-- <li class="playlist-item" onclick="changeVideo('video2.mp4', 'Video 2')">视频 2</li>-->
<!-- <li class="playlist-item" onclick="changeVideo('video3.mp4', 'Video 3')">视频 3</li>-->
{{end}}
</ul>
</div>
<script>
var video = document.getElementById('video');
var playlistItems = Array.from(document.getElementsByClassName('playlist-item'));
function changeVideo(source, title) {
video.src ="http://10.72.1.241:8080/GetFile/" + source;
// video.play();
// 更新选中状态和标题
playlistItems.forEach(function(item) {
item.classList.remove('active');
});
event.target.classList.add('active');
document.title = title;
}
</script>
</body>
</html>
演示截图:
可以有播放资源的滚动播放条了;
到此基本结束了,这个前端不在优化了,最终版本
=================================
1.1前端代码[参考不作为实际使用]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/* 视频播放器样式 */
#videoPlayer {
display: flex;
}
#video {
flex: 1;
}
/* 播放列表样式 */
.playlist {
list-style: none;
padding: 0;
width: 200px;
margin-left: 20px;
}
.playlist-item {
cursor: pointer;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: 10px;
}
.playlist-item:last-child {
margin-bottom: 0;
}
.playlist-item.active {
background-color: #f5f5f5;
}
li{
display: block;
}
</style>
</head>
<body>
<div id="videoPlayer">
<!-- <video id="video" width="420" height="340" controls></video>-->
<video id="video" width="420" height="340" controls="controls" src="http://10.72.1.241:8080/GetFile/a1.mp4"
type="video/ogg"></video></br>
<ul id="playlist" class="playlist">
{{range $index,$v := .names}}
<li class="playlist-item" onclick="changeVideo('{{$v }}', '{{$v }}')">{{$v }}</li><br>
<!-- <li class="playlist-item" onclick="changeVideo('video2.mp4', 'Video 2')">视频 2</li>-->
<!-- <li class="playlist-item" onclick="changeVideo('video3.mp4', 'Video 3')">视频 3</li>-->
{{end}}
</ul>
</div>
<script>
var video = document.getElementById('video');
var playlistItems = Array.from(document.getElementsByClassName('playlist-item'));
function changeVideo(source, title) {
video.src ="http://10.72.1.241:8080/GetFile/" + source;
// video.play();
// 更新选中状态和标题
playlistItems.forEach(function(item) {
item.classList.remove('active');
});
event.target.classList.add('active');
document.title = title;
}
</script>
</body>
</html>
1.2前端样式,播放器的最终样式;
二、后端代码
2.1后端代码
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
"github.com/gin-gonic/gin"
)
// 这个代码在windows,linux中都是可以使用,这里重点关注的就是
//
// videos := fmt.Sprintf("%s/%s", ml, "videos") 这样设置 windows linux都是可以使用
//
// 实现遍历程序的当前目录videos下的文件
func ListDir() ([]string, error) {
ml, _ := os.Getwd()
videos := fmt.Sprintf("%s/%s", ml, "videos")
infos, err := ioutil.ReadDir(videos)
if err != nil {
return nil, err
}
names := make([]string, len(infos))
for i, info := range infos {
//获取文件名 确认以*MP4结尾的放入切片中
filename := info.Name()
if strings.HasSuffix(filename, ".mp4") {
//if filename
names[i] = info.Name()
}
}
return names, nil
}
func ListDirllinux() ([]string, error) {
ml, _ := os.Getwd()
videos := fmt.Sprintf("%s//%s", ml, "videos")
infos, err := ioutil.ReadDir(videos)
if err != nil {
return nil, err
}
names := make([]string, len(infos))
for i, info := range infos {
//获取文件名 确认以*MP4结尾的放入切片中
filename := info.Name()
if strings.HasSuffix(filename, ".mp4") {
//if filename
names[i] = info.Name()
}
}
return names, nil
}
// 文件下载功能实现
func DowFile(c *gin.Context) {
//通过动态路由方式获取文件名,以实现下载不同文件的功能
name := c.Param("name")
//拼接路径,如果没有这一步,则默认在当前路径下寻找
filename := path.Join("./videos", name)
//响应一个文件
c.File(filename)
return
}
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
// 初始化默认静态资源
r.StaticFS("/videos", http.Dir("./videos"))
//windows 和linux下的路径稍微不同
names, _ := ListDir()
//names, _ := ListDirllinux()
r.GET("/index", func(c *gin.Context) {
//c.HTML(http.StatusOK, "index.html", gin.H{"names": names})
c.HTML(http.StatusOK, "newindexV1.html", gin.H{"names": names})
})
r.GET("/GetFile/:name", DowFile)
//r.Run()
r.Run("0.0.0.0:8080")
}
2.2后端代码组成样式
三、代码经历过程
简单版本视频播放服务器V2 https://blog.csdn.net/wtt234/article/details/131752840 简单版本视频播放服务器V1 https://blog.csdn.net/wtt234/article/details/131708946 简单播放器的打包过程,在不同平台如何打包事项 https://blog.csdn.net/wtt234/article/details/131728078
到这里经过几次修改基本完成了一个简单的视频服务,为家庭使用可以的,前端界面也优化了多个版本,以及打包过程