summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/app.go48
-rw-r--r--app/rice-box.go8
-rw-r--r--app/watcher.go3
-rw-r--r--media/library.go4
-rw-r--r--templates/index.html4
5 files changed, 60 insertions, 7 deletions
diff --git a/app/app.go b/app/app.go
index 3f99998..8899de1 100644
--- a/app/app.go
+++ b/app/app.go
@@ -178,12 +178,15 @@ func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, fmt.Sprintf("/v/%s?%s", pl[0].ID, r.URL.RawQuery), 302)
} else {
sort := strings.ToLower(r.URL.Query().Get("sort"))
+ quality := strings.ToLower(r.URL.Query().Get("quality"))
ctx := &struct {
Sort string
+ Quality string
Playing *media.Video
Playlist media.Playlist
}{
Sort: sort,
+ Quality: quality,
Playing: &media.Video{ID: ""},
Playlist: a.Library.Playlist(),
}
@@ -449,10 +452,16 @@ func (a *App) pageHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("/v/%s", id)
playing, ok := a.Library.Videos[id]
if !ok {
+ sort := strings.ToLower(r.URL.Query().Get("sort"))
+ quality := strings.ToLower(r.URL.Query().Get("quality"))
ctx := &struct {
+ Sort string
+ Quality string
Playing *media.Video
Playlist media.Playlist
}{
+ Sort: sort,
+ Quality: quality,
Playing: &media.Video{ID: ""},
Playlist: a.Library.Playlist(),
}
@@ -491,13 +500,23 @@ func (a *App) pageHandler(w http.ResponseWriter, r *http.Request) {
log.Warnf("invalid sort critiera: %s", sort)
}
+ quality := strings.ToLower(r.URL.Query().Get("quality"))
+ switch quality {
+ case "", "720p", "480p", "360p", "240p":
+ default:
+ log.WithField("quality", quality).Warn("invalid quality")
+ quality = ""
+ }
+
w.Header().Set("Content-Type", "text/html; charset=utf-8")
ctx := &struct {
Sort string
+ Quality string
Playing *media.Video
Playlist media.Playlist
}{
Sort: sort,
+ Quality: quality,
Playing: playing,
Playlist: playlist,
}
@@ -508,16 +527,43 @@ func (a *App) pageHandler(w http.ResponseWriter, r *http.Request) {
func (a *App) videoHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
+
prefix, ok := vars["prefix"]
if ok {
id = path.Join(prefix, id)
}
+
log.Printf("/v/%s", id)
+
m, ok := a.Library.Videos[id]
if !ok {
return
}
+ var videoPath string
+
+ quality := strings.ToLower(r.URL.Query().Get("quality"))
+ switch quality {
+ case "720p", "480p", "360p", "240p":
+ videoPath = fmt.Sprintf(
+ "%s#%s.mp4",
+ strings.TrimSuffix(m.Path, filepath.Ext(m.Path)),
+ quality,
+ )
+ if !utils.FileExists(videoPath) {
+ log.
+ WithField("quality", quality).
+ WithField("videoPath", videoPath).
+ Warn("video with specified quality does not exist (defaulting to default quality)")
+ videoPath = m.Path
+ }
+ case "":
+ videoPath = m.Path
+ default:
+ log.WithField("quality", quality).Warn("invalid quality")
+ videoPath = m.Path
+ }
+
if err := a.Store.Migrate(prefix, id); err != nil {
err := fmt.Errorf("error migrating store data: %w", err)
log.Warn(err)
@@ -532,7 +578,7 @@ func (a *App) videoHandler(w http.ResponseWriter, r *http.Request) {
disposition := "attachment; filename=\"" + title + ".mp4\""
w.Header().Set("Content-Disposition", disposition)
w.Header().Set("Content-Type", "video/mp4")
- http.ServeFile(w, r, m.Path)
+ http.ServeFile(w, r, videoPath)
}
// HTTP handler for /t/id
diff --git a/app/rice-box.go b/app/rice-box.go
index a603db4..83bc264 100644
--- a/app/rice-box.go
+++ b/app/rice-box.go
@@ -23,9 +23,9 @@ func init() {
}
file4 := &embedded.EmbeddedFile{
Filename: "index.html",
- FileModTime: time.Unix(1585371597, 0),
+ FileModTime: time.Unix(1585374250, 0),
- Content: string("{{ define \"content\" }}\r\n{{ $playing := .Playing }}\r\n<div id=\"player\">\r\n {{ if $playing.ID }}\r\n <video id=\"video\" controls preload=\"metadata\" poster=\"/t/{{ $playing.ID}}\" src=\"/v/{{ $playing.ID }}.mp4\" type=\"video/mp4\"></video>\r\n <h1>{{ $playing.Title }}</h1>\r\n <h2>{{ $playing.Views }} views • {{ $playing.Modified }}<br />{{ $playing.Size | bytes }}</h2>\r\n <p>{{ $playing.Description }}</p>\r\n {{ else }}\r\n <video id=\"video\" controls></video>\r\n {{ end }}\r\n</div>\r\n<div id=\"playlist\">\r\n <div class=\"nav\">\r\n <ul>\r\n <li><a {{ if or (eq $.Sort \"timestamp\") (eq $.Sort \"\") }}class=\"active\"{{ end }} href=\"?sort=timestamp\">Recent</a></li>\r\n <li><a {{ if eq $.Sort \"views\" }}class=\"active\"{{ end }} href=\"?sort=views\">Views</a></li>\r\n </ul>\r\n </div>\r\n {{ range $m := .Playlist }}\r\n {{ if eq $m.ID $playing.ID }}\r\n <a href=\"/v/{{ $m.ID }}\" class=\"playing\">\r\n {{ else }}\r\n <a href=\"/v/{{ $m.ID }}\">\r\n {{ end }}\r\n <img src=\"/t/{{ $m.ID }}\">\r\n <div>\r\n <h1>{{ $m.Title }}</h1>\r\n <h2>{{ $m.Views }} views • {{ $m.Modified }}<br />{{ $m.Size | bytes }}</h2>\r\n </div>\r\n </a>\r\n {{ end }}\r\n</div>\r\n{{end}}\r\n"),
+ Content: string("{{ define \"content\" }}\r\n{{ $playing := .Playing }}\r\n<div id=\"player\">\r\n {{ if $playing.ID }}\r\n <video id=\"video\" controls preload=\"metadata\" poster=\"/t/{{ $playing.ID}}\">\r\n <source src=\"/v/{{ $playing.ID }}.mp4?quality={{ $.Quality }}\" type=\"video/mp4\" />\r\n </video>\r\n <h1>{{ $playing.Title }}</h1>\r\n <h2>{{ $playing.Views }} views • {{ $playing.Modified }}<br />{{ $playing.Size | bytes }}</h2>\r\n <p>{{ $playing.Description }}</p>\r\n {{ else }}\r\n <video id=\"video\" controls></video>\r\n {{ end }}\r\n</div>\r\n<div id=\"playlist\">\r\n <div class=\"nav\">\r\n <ul>\r\n <li><a {{ if or (eq $.Sort \"timestamp\") (eq $.Sort \"\") }}class=\"active\"{{ end }} href=\"?sort=timestamp\">Recent</a></li>\r\n <li><a {{ if eq $.Sort \"views\" }}class=\"active\"{{ end }} href=\"?sort=views\">Views</a></li>\r\n </ul>\r\n </div>\r\n {{ range $m := .Playlist }}\r\n {{ if eq $m.ID $playing.ID }}\r\n <a href=\"/v/{{ $m.ID }}\" class=\"playing\">\r\n {{ else }}\r\n <a href=\"/v/{{ $m.ID }}\">\r\n {{ end }}\r\n <img src=\"/t/{{ $m.ID }}\">\r\n <div>\r\n <h1>{{ $m.Title }}</h1>\r\n <h2>{{ $m.Views }} views • {{ $m.Modified }}<br />{{ $m.Size | bytes }}</h2>\r\n </div>\r\n </a>\r\n {{ end }}\r\n</div>\r\n{{end}}\r\n"),
}
file5 := &embedded.EmbeddedFile{
Filename: "upload.html",
@@ -37,7 +37,7 @@ func init() {
// define dirs
dir1 := &embedded.EmbeddedDir{
Filename: "",
- DirModTime: time.Unix(1585371597, 0),
+ DirModTime: time.Unix(1585374250, 0),
ChildFiles: []*embedded.EmbeddedFile{
file2, // "base.html"
file3, // "import.html"
@@ -53,7 +53,7 @@ func init() {
// register embeddedBox
embedded.RegisterEmbeddedBox(`../templates`, &embedded.EmbeddedBox{
Name: `../templates`,
- Time: time.Unix(1585371597, 0),
+ Time: time.Unix(1585374250, 0),
Dirs: map[string]*embedded.EmbeddedDir{
"": dir1,
},
diff --git a/app/watcher.go b/app/watcher.go
index 000df02..e08dff5 100644
--- a/app/watcher.go
+++ b/app/watcher.go
@@ -2,6 +2,7 @@ package app
import (
"path/filepath"
+ "strings"
"time"
fs "github.com/fsnotify/fsnotify"
@@ -29,7 +30,7 @@ func startWatcher(a *App) {
for {
select {
case e := <-a.Watcher.Events:
- if filepath.Ext(e.Name) != ".mp4" {
+ if strings.ContainsAny(e.Name, "#") || filepath.Ext(e.Name) != ".mp4" {
continue
}
log.Debugf("fsnotify event: %s", e)
diff --git a/media/library.go b/media/library.go
index 0a0b522..5ea20e3 100644
--- a/media/library.go
+++ b/media/library.go
@@ -50,6 +50,10 @@ func (lib *Library) Import(p *Path) error {
return err
}
for _, info := range files {
+ if strings.ContainsAny(info.Name(), "#") {
+ // ignore resized videos e.g: #240p.mp4
+ continue
+ }
err = lib.Add(path.Join(p.Path, info.Name()))
if err != nil {
// Ignore files that can't be parsed
diff --git a/templates/index.html b/templates/index.html
index aea20cb..5d8cd18 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -2,7 +2,9 @@
{{ $playing := .Playing }}
<div id="player">
{{ if $playing.ID }}
- <video id="video" controls preload="metadata" poster="/t/{{ $playing.ID}}" src="/v/{{ $playing.ID }}.mp4" type="video/mp4"></video>
+ <video id="video" controls preload="metadata" poster="/t/{{ $playing.ID}}">
+ <source src="/v/{{ $playing.ID }}.mp4?quality={{ $.Quality }}" type="video/mp4" />
+ </video>
<h1>{{ $playing.Title }}</h1>
<h2>{{ $playing.Views }} views • {{ $playing.Modified }}<br />{{ $playing.Size | bytes }}</h2>
<p>{{ $playing.Description }}</p>