代码优化

This commit is contained in:
kenneth
2023-12-01 07:35:00 +00:00
parent 26c1f6aa72
commit a2b0cd71b3
14 changed files with 357 additions and 381 deletions

View File

@@ -8,16 +8,22 @@ import (
"github.com/zhang2092/mediahls/internal/db"
)
type pageData struct {
// obj
// homePageData 首页数据
type homePageData struct {
Authorize
Videos []db.Video
}
func (server *Server) home(w http.ResponseWriter, r *http.Request) {
pd := pageData{}
// view
// home 首页
func (server *Server) homeView(w http.ResponseWriter, r *http.Request) {
data := homePageData{}
auth, err := server.withCookie(r)
if err == nil {
pd.Authorize = *auth
data.Authorize = *auth
}
ctx := r.Context()
@@ -32,12 +38,9 @@ func (server *Server) home(w http.ResponseWriter, r *http.Request) {
item.Description = temp
log.Println(item.Description)
}
pd.Videos = append(pd.Videos, item)
data.Videos = append(data.Videos, item)
}
}
renderHome(w, pd)
}
func renderHome(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/home.html.tmpl")
}

View File

@@ -33,14 +33,13 @@ func (server *Server) authorizeMiddleware(next http.Handler) http.Handler {
func (server *Server) withCookie(r *http.Request) (*Authorize, error) {
cookie, err := r.Cookie(AuthorizeCookie)
if err != nil {
log.Printf("get cookie: %v", err)
return nil, err
}
u := &Authorize{}
err = server.secureCookie.Decode(AuthorizeCookie, cookie.Value, u)
if err != nil {
log.Printf("secure decode cookie: %v", err)
// log.Printf("secure decode cookie: %v", err)
return nil, err
}

View File

@@ -2,8 +2,9 @@ package handlers
import (
"html/template"
"log"
"net/http"
"github.com/zhang2092/mediahls/internal/pkg/logger"
)
// func render(w http.ResponseWriter, data any, tmpls ...string) {
@@ -22,18 +23,19 @@ import (
// }
// }
// renderLayout 渲染方法 带框架
func renderLayout(w http.ResponseWriter, data any, tmpls ...string) {
tmpls = append(tmpls, "web/templates/base/header.html.tmpl", "web/templates/base/footer.html.tmpl")
t, err := template.ParseFiles(tmpls...)
if err != nil {
log.Printf("template parse: %v", err)
logger.Logger.Errorf("template parse: %v, %v", tmpls, err)
w.WriteHeader(http.StatusInternalServerError)
return
}
err = t.Execute(w, data)
if err != nil {
log.Printf("template execute: %v", err)
logger.Logger.Errorf("template execute: %v, %v", tmpls, err)
w.WriteHeader(http.StatusInternalServerError)
return
}

View File

@@ -62,23 +62,25 @@ func (server *Server) setupRouter() {
router.HandleFunc("/login", server.loginView).Methods(http.MethodGet)
router.HandleFunc("/login", server.login).Methods(http.MethodPost)
router.HandleFunc("/logout", server.logout).Methods(http.MethodGet)
router.HandleFunc("/", server.home).Methods(http.MethodGet)
router.HandleFunc("/play/{xid}", server.play).Methods(http.MethodGet)
router.HandleFunc("/", server.homeView).Methods(http.MethodGet)
router.HandleFunc("/play/{xid}", server.videoView).Methods(http.MethodGet)
router.HandleFunc("/media/{xid}/stream/", server.stream).Methods(http.MethodGet)
router.HandleFunc("/media/{xid}/stream/{segName:index[0-9]+.ts}", server.stream).Methods(http.MethodGet)
subRouter := router.PathPrefix("/").Subrouter()
subRouter.Use(server.authorizeMiddleware)
subRouter.HandleFunc("/me/videos", server.videosView).Methods(http.MethodGet)
subRouter.HandleFunc("/me/videos/p{page}", server.videosView).Methods(http.MethodGet)
subRouter.HandleFunc("/me/videos/create", server.createVideoView).Methods(http.MethodGet)
subRouter.HandleFunc("/me/videos/create/{xid}", server.createVideoView).Methods(http.MethodGet)
subRouter.HandleFunc("/me/videos/create", server.createVideo).Methods(http.MethodPost)
subRouter.HandleFunc("/me/videos/update", server.editVideoView).Methods(http.MethodGet)
subRouter.HandleFunc("/me/videos/update/{xid}", server.editVideoView).Methods(http.MethodGet)
subRouter.HandleFunc("/me/videos/update", server.editVideo).Methods(http.MethodPost)
subRouter.HandleFunc("/upload_image", server.uploadImage).Methods(http.MethodPost)
subRouter.HandleFunc("/upload_file", server.uploadVideo).Methods(http.MethodPost)
subRouter.HandleFunc("/transfer/{xid}", server.transferView).Methods(http.MethodGet)
subRouter.HandleFunc("/transfer/{xid}", server.transfer).Methods(http.MethodPost)
server.router = router

View File

@@ -4,7 +4,6 @@ import (
"bufio"
"errors"
"io"
"log"
"net/http"
"os"
"path"
@@ -13,18 +12,20 @@ import (
nanoId "github.com/matoous/go-nanoid"
"github.com/zhang2092/mediahls/internal/pkg/fileutil"
"github.com/zhang2092/mediahls/internal/pkg/logger"
)
// data
// uploadVideo 上传视频
func (server *Server) uploadVideo(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
file, fileHeader, err := r.FormFile("file")
if err != nil {
logger.Logger.Errorf("upload video receive: %v", err)
w.WriteHeader(http.StatusBadRequest)
_, err = w.Write([]byte(err.Error()))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte(err.Error()))
return
}
defer file.Close()
@@ -81,12 +82,10 @@ func (server *Server) uploadVideo(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusOK)
_, err = w.Write([]byte("/" + filePath))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte("/" + filePath))
}
// uploadImage 上传图片
func (server *Server) uploadImage(w http.ResponseWriter, r *http.Request) {
defer func(Body io.ReadCloser) {
_ = Body.Close()
@@ -94,49 +93,33 @@ func (server *Server) uploadImage(w http.ResponseWriter, r *http.Request) {
_, fh, err := r.FormFile("file")
if err != nil {
logger.Logger.Errorf("upload image receive: %v", err)
w.WriteHeader(http.StatusBadRequest)
_, err = w.Write([]byte(err.Error()))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte(err.Error()))
return
}
f, err := fh.Open()
if err != nil {
log.Printf("%v", err)
logger.Logger.Errorf("upload image read: %v", err)
w.WriteHeader(http.StatusInternalServerError)
_, err = w.Write([]byte("读取图片失败"))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte("读取图片失败"))
return
}
reader := bufio.NewReader(f)
filePath, err := fileutil.UploadImage(reader)
if errors.Is(err, fileutil.ErrUnsupportedFileFormat) {
log.Printf("%v", err)
w.WriteHeader(http.StatusUnsupportedMediaType)
_, err = w.Write([]byte(fileutil.ErrUnsupportedFileFormat.Error()))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte(fileutil.ErrUnsupportedFileFormat.Error()))
return
}
if err != nil {
log.Printf("%v", err)
w.WriteHeader(http.StatusInternalServerError)
_, err = w.Write([]byte(err.Error()))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusOK)
_, err = w.Write([]byte(filePath))
if err != nil {
log.Printf("%v", err)
}
w.Write([]byte(filePath))
}

View File

@@ -10,67 +10,49 @@ import (
pwd "github.com/zhang2092/mediahls/internal/pkg/password"
)
// obj
// registerPageData 注册页面数据
type registerPageData struct {
Authorize
Summary string
Email string
EmailMsg string
Username string
UsernameMsg string
Password string
PasswordMsg string
}
// loginPageData 登录页面数据
type loginPageData struct {
Authorize
Summary string
Email string
EmailMsg string
Password string
PasswordMsg string
}
// view
// registerView 注册页面
func (server *Server) registerView(w http.ResponseWriter, r *http.Request) {
// 是否已经登录
server.isRedirect(w, r)
renderRegister(w, nil)
}
func renderRegister(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/user/register.html.tmpl")
// loginView 登录页面
func (server *Server) loginView(w http.ResponseWriter, r *http.Request) {
// 是否已经登录
server.isRedirect(w, r)
renderLogin(w, nil)
}
// type userResponse struct {
// Username string `json:"username"`
// FullName string `json:"full_name"`
// Email string `json:"email"`
// PasswordChangedAt time.Time `json:"password_changed_at"`
// CreatedAt time.Time `json:"created_at"`
// }
// func newUserResponse(user db.User) userResponse {
// return userResponse{
// Username: user.Username,
// Email: user.Email,
// CreatedAt: user.CreatedAt,
// }
// }
func viladatorRegister(email, username, password string) (*respErrs, bool) {
ok := true
errs := &respErrs{
Email: email,
Username: username,
Password: password,
}
if !ValidateRxEmail(email) {
errs.EmailErr = "请填写正确的邮箱地址"
ok = false
}
if !ValidateRxUsername(username) {
errs.UsernameErr = "名称(6-20,字母,数字)"
ok = false
}
if !ValidatePassword(password) {
errs.PasswordErr = "密码(8-20位)"
ok = false
}
return errs, ok
}
type respErrs struct {
Authorize
Summary string
Email string
Username string
Password string
EmailErr string
UsernameErr string
PasswordErr string
}
// data
// register 注册
func (server *Server) register(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
@@ -82,9 +64,9 @@ func (server *Server) register(w http.ResponseWriter, r *http.Request) {
email := r.PostFormValue("email")
username := r.PostFormValue("username")
password := r.PostFormValue("password")
errs, ok := viladatorRegister(email, username, password)
resp, ok := viladatorRegister(email, username, password)
if !ok {
renderRegister(w, errs)
renderRegister(w, resp)
return
}
@@ -104,70 +86,33 @@ func (server *Server) register(w http.ResponseWriter, r *http.Request) {
_, err = server.store.CreateUser(r.Context(), arg)
if err != nil {
if server.store.IsUniqueViolation(err) {
errs.Summary = "邮箱或名称已经存在"
renderRegister(w, errs)
resp.Summary = "邮箱或名称已经存在"
renderRegister(w, resp)
return
}
errs.Summary = "请求网络错误,请刷新重试"
renderRegister(w, errs)
resp.Summary = "请求网络错误,请刷新重试"
renderRegister(w, resp)
return
}
http.Redirect(w, r, "/login", http.StatusFound)
// rsp := newUserResponse(user)
// Respond(w, "ok", rsp, http.StatusOK)
}
func (server *Server) loginView(w http.ResponseWriter, r *http.Request) {
// 是否已经登录
server.isRedirect(w, r)
renderLogin(w, nil)
}
func renderLogin(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/user/login.html.tmpl")
}
// type loginUserResponse struct {
// AccessToken string `json:"access_token"`
// AccessTokenExpiresAt time.Time `json:"access_token_expires_at"`
// User userResponse `json:"user"`
// }
func viladatorLogin(email, password string) (*respErrs, bool) {
ok := true
errs := &respErrs{
Email: email,
Password: password,
}
if !ValidateRxEmail(email) {
errs.EmailErr = "请填写正确的邮箱地址"
ok = false
}
if len(password) == 0 {
errs.PasswordErr = "请填写正确的密码"
ok = false
}
return errs, ok
}
// login 登录
func (server *Server) login(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if err := r.ParseForm(); err != nil {
renderLogin(w, respErrs{Summary: "请求网络错误,请刷新重试"})
renderLogin(w, registerPageData{Summary: "请求网络错误,请刷新重试"})
return
}
email := r.PostFormValue("email")
password := r.PostFormValue("password")
errs, ok := viladatorLogin(email, password)
resp, ok := viladatorLogin(email, password)
if !ok {
renderLogin(w, errs)
renderLogin(w, resp)
return
}
@@ -175,27 +120,27 @@ func (server *Server) login(w http.ResponseWriter, r *http.Request) {
user, err := server.store.GetUserByEmail(ctx, email)
if err != nil {
if server.store.IsNoRows(sql.ErrNoRows) {
errs.Summary = "邮箱或密码错误"
renderLogin(w, errs)
resp.Summary = "邮箱或密码错误"
renderLogin(w, resp)
return
}
errs.Summary = "请求网络错误,请刷新重试"
renderLogin(w, errs)
resp.Summary = "请求网络错误,请刷新重试"
renderLogin(w, resp)
return
}
err = pwd.BcryptComparePassword(user.HashedPassword, password)
if err != nil {
errs.Summary = "邮箱或密码错误"
renderLogin(w, errs)
resp.Summary = "邮箱或密码错误"
renderLogin(w, resp)
return
}
encoded, err := server.secureCookie.Encode(AuthorizeCookie, &Authorize{ID: user.ID, Name: user.Username})
if err != nil {
errs.Summary = "请求网络错误,请刷新重试(cookie)"
renderLogin(w, errs)
resp.Summary = "请求网络错误,请刷新重试(cookie)"
renderLogin(w, resp)
return
}
@@ -204,7 +149,65 @@ func (server *Server) login(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusFound)
}
// logout 退出
func (server *Server) logout(w http.ResponseWriter, r *http.Request) {
cookie.DeleteCookie(w, cookie.AuthorizeName)
http.Redirect(w, r, "/login", http.StatusFound)
}
// method
// renderRegister 渲染注册页面
func renderRegister(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/user/register.html.tmpl")
}
// renderLogin 渲染登录页面
func renderLogin(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/user/login.html.tmpl")
}
// viladatorRegister 校验注册数据
func viladatorRegister(email, username, password string) (registerPageData, bool) {
ok := true
resp := registerPageData{
Email: email,
Username: username,
Password: password,
}
if !ValidateRxEmail(email) {
resp.EmailMsg = "请填写正确的邮箱地址"
ok = false
}
if !ValidateRxUsername(username) {
resp.UsernameMsg = "名称(6-20,字母,数字)"
ok = false
}
if !ValidatePassword(password) {
resp.PasswordMsg = "密码(8-20位)"
ok = false
}
return resp, ok
}
// viladatorLogin 校验登录数据
func viladatorLogin(email, password string) (loginPageData, bool) {
ok := true
errs := loginPageData{
Email: email,
Password: password,
}
if !ValidateRxEmail(email) {
errs.EmailMsg = "请填写正确的邮箱地址"
ok = false
}
if len(password) == 0 {
errs.PasswordMsg = "请填写正确的密码"
ok = false
}
return errs, ok
}

View File

@@ -15,18 +15,48 @@ import (
"github.com/zhang2092/mediahls/internal/pkg/logger"
)
type playData struct {
// obj
// videoPageData 播放页面数据
type videoPageData struct {
Authorize
Url string
Video db.Video
}
func (server *Server) play(w http.ResponseWriter, r *http.Request) {
// videosPageData 视频列表数据
type videosPageData struct {
Authorize
Videos []db.Video
}
// videoEditPageData 视频编辑数据
type videoEditPageData struct {
Authorize
Summary string
ID string
IDMsg string
Title string
TitleMsg string
Images string
ImagesMsg string
Description string
DescriptionMsg string
OriginLink string
OriginLinkMsg string
Status int
StatusMsg string
}
// view
// videoView 视频播放页面
func (server *Server) videoView(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
xid := vars["xid"]
video, _ := server.store.GetVideo(r.Context(), xid)
data := playData{
Video: video,
data := videoPageData{}
video, err := server.store.GetVideo(r.Context(), xid)
if err == nil {
data.Video = video
}
auth, err := server.withCookie(r)
if err == nil {
@@ -35,59 +65,10 @@ func (server *Server) play(w http.ResponseWriter, r *http.Request) {
renderLayout(w, data, "web/templates/video/play.html.tmpl")
}
/*
// 直接播放mp4
video, err := os.Open("web/statics/git.mp4")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("failed to open file"))
return
}
defer video.Close()
http.ServeContent(w, r, "git", time.Now(), video)
*/
func (server *Server) stream(response http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
mId := vars["xid"]
segName, ok := vars["segName"]
if !ok {
mediaBase := getMediaBase(mId)
m3u8Name := "index.m3u8"
serveHlsM3u8(response, request, mediaBase, m3u8Name)
} else {
mediaBase := getMediaBase(mId)
serveHlsTs(response, request, mediaBase, segName)
}
}
func getMediaBase(mId string) string {
mediaRoot := "media"
return fmt.Sprintf("%s/%s", mediaRoot, mId)
}
func serveHlsM3u8(w http.ResponseWriter, r *http.Request, mediaBase, m3u8Name string) {
mediaFile := fmt.Sprintf("%s/%s", mediaBase, m3u8Name)
http.ServeFile(w, r, mediaFile)
w.Header().Set("Content-Type", "application/x-mpegURL")
}
func serveHlsTs(w http.ResponseWriter, r *http.Request, mediaBase, segName string) {
mediaFile := fmt.Sprintf("%s/%s", mediaBase, segName)
http.ServeFile(w, r, mediaFile)
w.Header().Set("Content-Type", "video/MP2T")
}
type meVideoData struct {
Authorize
Videos []db.Video
}
// videosView 视频列表页面
func (server *Server) videosView(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
data := meVideoData{
data := videosPageData{
Authorize: withUser(ctx),
}
@@ -111,13 +92,14 @@ func (server *Server) videosView(w http.ResponseWriter, r *http.Request) {
}
}
renderLayout(w, data, "web/templates/me/videos.html.tmpl")
renderLayout(w, data, "web/templates/video/videos.html.tmpl")
}
func (server *Server) createVideoView(w http.ResponseWriter, r *http.Request) {
// editVideoView 视频编辑页面
func (server *Server) editVideoView(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
xid := vars["xid"]
vm := videoCreateResp{
vm := videoEditPageData{
Authorize: withUser(r.Context()),
}
if len(xid) > 0 {
@@ -130,79 +112,38 @@ func (server *Server) createVideoView(w http.ResponseWriter, r *http.Request) {
vm.Status = int(v.Status)
}
}
renderCreateVideo(w, vm)
renderEditVideo(w, vm)
}
func renderCreateVideo(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/video/edit.html.tmpl")
// data
// stream 视频HLS播放处理
func (server *Server) stream(response http.ResponseWriter, request *http.Request) {
vars := mux.Vars(request)
mId := vars["xid"]
segName, ok := vars["segName"]
if !ok {
mediaBase := getMediaBase(mId)
m3u8Name := "index.m3u8"
serveHlsM3u8(response, request, mediaBase, m3u8Name)
} else {
mediaBase := getMediaBase(mId)
serveHlsTs(response, request, mediaBase, segName)
}
}
type videoCreateResp struct {
Authorize
Summary string
ID string
IDErr string
Title string
TitleErr string
Images string
ImagesErr string
Description string
DescriptionErr string
OriginLink string
OriginLinkErr string
Status int
StatusErr string
}
func viladatorCreateVedio(r *http.Request) (*videoCreateResp, bool) {
ok := true
status, _ := strconv.Atoi(r.PostFormValue("status"))
errs := &videoCreateResp{
Authorize: withUser(r.Context()),
ID: r.PostFormValue("id"),
Title: r.PostFormValue("title"),
Images: r.PostFormValue("images"),
Description: r.PostFormValue("description"),
OriginLink: r.PostFormValue("origin_link"),
Status: status,
}
if len(errs.Title) == 0 {
errs.TitleErr = "请填写正确的标题"
ok = false
}
exist, _ := fileutil.PathExists(strings.TrimPrefix(errs.Images, "/"))
if !exist {
errs.ImagesErr = "请先上传图片"
ok = false
}
if len(errs.Description) == 0 {
errs.DescriptionErr = "请填写描述"
ok = false
}
exist, _ = fileutil.PathExists(strings.TrimPrefix(errs.OriginLink, "/"))
if !exist {
errs.OriginLinkErr = "请先上传视频"
ok = false
}
return errs, ok
}
func (server *Server) createVideo(w http.ResponseWriter, r *http.Request) {
// editVideo 视频编辑
func (server *Server) editVideo(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if err := r.ParseForm(); err != nil {
renderCreateVideo(w, videoCreateResp{Summary: "请求网络错误, 请刷新重试"})
renderEditVideo(w, videoEditPageData{Summary: "请求网络错误, 请刷新重试"})
return
}
vm, ok := viladatorCreateVedio(r)
vm, ok := viladatorEditVedio(r)
if !ok {
renderCreateVideo(w, vm)
renderEditVideo(w, vm)
return
}
@@ -222,22 +163,34 @@ func (server *Server) createVideo(w http.ResponseWriter, r *http.Request) {
})
if err != nil {
vm.Summary = "添加视频失败"
renderCreateVideo(w, vm)
renderEditVideo(w, vm)
return
}
} else {
_, err := server.store.UpdateVideo(ctx, db.UpdateVideoParams{
v, err := server.store.GetVideo(ctx, vm.ID)
if err != nil {
vm.Summary = "视频数据错误"
renderEditVideo(w, vm)
return
}
var sta int32 = int32(vm.Status)
if sta != -1 && sta != 200 {
sta = v.Status
}
_, err = server.store.UpdateVideo(ctx, db.UpdateVideoParams{
ID: vm.ID,
Title: vm.Title,
Description: vm.Description,
Images: vm.Images,
Status: int32(vm.Status),
Status: sta,
UpdateAt: curTime,
UpdateBy: u.Name,
})
if err != nil {
vm.Summary = "更新视频失败"
renderCreateVideo(w, vm)
renderEditVideo(w, vm)
return
}
}
@@ -245,25 +198,7 @@ func (server *Server) createVideo(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/me/videos", http.StatusFound)
}
type transferData struct {
Authorize
Video db.Video
}
func (server *Server) transferView(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
xid := vars["xid"]
v, _ := server.store.GetVideo(r.Context(), xid)
data := transferData{
Video: v,
}
u, err := server.withCookie(r)
if err == nil {
data.Authorize = *u
}
renderLayout(w, data, "web/templates/video/transfer.html.tmpl")
}
// transfer 视频转码
func (server *Server) transfer(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
xid := vars["xid"]
@@ -318,3 +253,82 @@ func (server *Server) transfer(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("视频正在转码中, 请稍后刷新页面"))
}
// method
// renderEditVideo 渲染视频编辑页面
func renderEditVideo(w http.ResponseWriter, data any) {
renderLayout(w, data, "web/templates/video/edit.html.tmpl")
}
// viladatorEditVedio 检验视频编辑数据
func viladatorEditVedio(r *http.Request) (videoEditPageData, bool) {
ok := true
status, _ := strconv.Atoi(r.PostFormValue("status"))
resp := videoEditPageData{
Authorize: withUser(r.Context()),
ID: r.PostFormValue("id"),
Title: r.PostFormValue("title"),
Images: r.PostFormValue("images"),
Description: r.PostFormValue("description"),
OriginLink: r.PostFormValue("origin_link"),
Status: status,
}
if len(resp.Title) == 0 {
resp.TitleMsg = "请填写正确的标题"
ok = false
}
exist, _ := fileutil.PathExists(strings.TrimPrefix(resp.Images, "/"))
if !exist {
resp.ImagesMsg = "请先上传图片"
ok = false
}
if len(resp.Description) == 0 {
resp.DescriptionMsg = "请填写描述"
ok = false
}
exist, _ = fileutil.PathExists(strings.TrimPrefix(resp.OriginLink, "/"))
if !exist {
resp.OriginLinkMsg = "请先上传视频"
ok = false
}
return resp, ok
}
// getMediaBase 获取视频m3u8文件路径
func getMediaBase(mId string) string {
mediaRoot := "media"
return fmt.Sprintf("%s/%s", mediaRoot, mId)
}
// serveHlsM3u8 返回m3u8文件
func serveHlsM3u8(w http.ResponseWriter, r *http.Request, mediaBase, m3u8Name string) {
mediaFile := fmt.Sprintf("%s/%s", mediaBase, m3u8Name)
http.ServeFile(w, r, mediaFile)
w.Header().Set("Content-Type", "application/x-mpegURL")
}
// serveHlsTs 返回ts文件
func serveHlsTs(w http.ResponseWriter, r *http.Request, mediaBase, segName string) {
mediaFile := fmt.Sprintf("%s/%s", mediaBase, segName)
http.ServeFile(w, r, mediaFile)
w.Header().Set("Content-Type", "video/MP2T")
}
/*
// 直接播放mp4
video, err := os.Open("web/statics/git.mp4")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("failed to open file"))
return
}
defer video.Close()
http.ServeContent(w, r, "git", time.Now(), video)
*/