这是一个电影播放的静态文件服务器,缘于那台不好安装软件的Arm Win11:不少的视频软件都不支持WinArm版。那就直接在浏览器里播放就好。而实际上有些浏览器点击就下载。
package main
import (
"flag"
"fmt"
"log"
"net/http"
"strings"
"github.com/gorilla/mux"
)
var (
WebServer string
ServerDir string
)
const PlayPage = `
<!DOCTYPE html>
<html>
<style>
*{padding:0px;margin:0px;height:100%s;}
</style>
<body>
<video controls="controls" autoplay="autoplay">
<source src="%s" type="video/mp4" />
</video>
</body>
</html>
`
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var url string
// 包含 /open_movie 开头,则为播放视频,直接返回静态视频文件
if strings.HasPrefix(r.RequestURI, "/open_movie") {
r.URL.Path = strings.Replace(r.RequestURI, "/open_movie", "", 1)
next.ServeHTTP(w, r)
} else {
log.Print(r.RequestURI)
// 视频文件结尾,则嵌入播放页面代码
if r.TLS == nil {
url = fmt.Sprintf("http://%s/open_movie%s", r.Host, r.RequestURI)
} else {
url = fmt.Sprintf("https://%s/open_movie%s", r.Host, r.RequestURI)
}
u := strings.ToLower(url)
// 嵌入播放代码,支持mkv,mp4
if strings.HasSuffix(u, ".mp4") || strings.HasSuffix(u, ".mkv") {
fmt.Fprintf(w, fmt.Sprintf(PlayPage, "%%", url))
} else {
next.ServeHTTP(w, r)
}
}
})
}
func init() {
flag.StringVar(&WebServer, "w", "0.0.0.0:80", "Web服务端口")
flag.StringVar(&ServerDir, "d", "./", "服务目录")
flag.Parse()
}
func main() {
r := mux.NewRouter()
r.Use(Middleware) // 中间件
r.Handle("/", http.FileServer(http.Dir(ServerDir))) // 静态文件处理
r.Handle("/{content}", http.FileServer(http.Dir(ServerDir))) // 静态文件处理
r.Handle("/open_movie/{content}", http.FileServer(http.Dir(ServerDir))) // 静态文件处理
log.Print("服务运行于 ", WebServer, " , 服务目录 ", ServerDir)
http.ListenAndServe(WebServer, r)
}
代码很简单,也不优雅,还出现了%%的问题。先用着。
再版修改
package main
import (
"flag"
"fmt"
"log"
"net/http"
"net/url"
"strings"
)
var (
WebServer string
ServerDir string
AddCode = `
<style>
a{font-size:22px;display:block;text-decoration:none;padding:10px;}
.hovered {color: red;margin-left:10px;}
</style>
<script>
var aLinks = document.getElementsByTagName('a'); // 获取所有的<a>元素
// 遍历<a>元素并添加事件监听器
for (var i = 0; i < aLinks.length; i++) {
aLinks[i].addEventListener('mouseover', function() {
this.classList.add('hovered'); // 鼠标移入时的处理逻辑
});
aLinks[i].addEventListener('mouseout', function() {
this.classList.remove('hovered');// 鼠标移出时的处理逻辑
});
}
</script>
`
PlayPage = `
<!DOCTYPE html>
<html>
<title>文件浏览</title>
<style>
*{ padding:0px;margin:0px;height:100%s; }
</style>
<body>
<video controls="controls" autoplay="autoplay">
<source src="%s" type="video/%s" />
</video>
</body>
</html>
`
)
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var urlStr string
// 包含 /open_movie 开头,则为播放视频,直接返回静态视频文件
if strings.HasPrefix(r.RequestURI, "/open_movie") {
r.URL.Path, _ = url.QueryUnescape(strings.Replace(r.RequestURI, "/open_movie", "", 1))
next.ServeHTTP(w, r)
} else {
// 视频文件结尾,则嵌入播放页面代码
if r.TLS == nil {
urlStr = fmt.Sprintf("http://%s/open_movie%s", r.Host, r.RequestURI)
} else {
urlStr = fmt.Sprintf("https://%s/open_movie%s", r.Host, r.RequestURI)
}
unUrl, _ := url.QueryUnescape(urlStr)
if strings.HasSuffix(urlStr, "favicon.ico") {
log.Print(unUrl)
}
u := strings.ToLower(urlStr)
// 嵌入播放代码,支持mkv,mp4(mkv可能存在问题)
if strings.HasSuffix(u, ".mp4") {
fmt.Fprintf(w, fmt.Sprintf(PlayPage, "%%", unUrl, "mp4"))
} else if strings.HasSuffix(u, ".mkv") {
fmt.Fprintf(w, fmt.Sprintf(PlayPage, "%%", unUrl, "mkv"))
} else {
next.ServeHTTP(w, r)
}
}
})
}
func defaultPageHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
fmt.Fprintf(w, AddCode) // 补充代码,实现样式和一些功能
}
}
func init() {
flag.StringVar(&WebServer, "w", "0.0.0.0:80", "Web服务端口")
flag.StringVar(&ServerDir, "d", "./", "服务目录")
flag.Parse()
}
func main() {
fs := http.FileServer(http.Dir(ServerDir))
http.Handle("/", Middleware(defaultPageHandler(fs)))
log.Print("服务运行于 ", WebServer, " , 服务目录 ", ServerDir)
http.ListenAndServe(WebServer, nil)
}