Try serving media locally
This commit is contained in:
parent
23c7f8e520
commit
d91b1baebc
2 changed files with 54 additions and 5 deletions
|
@ -105,6 +105,9 @@ a:hover {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
.media-video {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<h1>Twitterchiver: {{.TwitterUsername}}</h1>
|
<h1>Twitterchiver: {{.TwitterUsername}}</h1>
|
||||||
{{if .Query}}
|
{{if .Query}}
|
||||||
|
@ -141,9 +144,19 @@ a:hover {
|
||||||
<div class="media">
|
<div class="media">
|
||||||
{{range $entity := .Object.extended_entities.media}}
|
{{range $entity := .Object.extended_entities.media}}
|
||||||
<div class="media-item">
|
<div class="media-item">
|
||||||
<a href="{{$entity.expanded_url}}" class="media-link">
|
{{if eq $entity.type "video"}}
|
||||||
<img src="{{$entity.media_url_https}}" class="media-img">
|
<video controls poster="{{rewriteURL $entity.media_url_https}}" class="media-video">
|
||||||
</a>
|
{{with bestVariant $entity.video_info.variants}}
|
||||||
|
{{if .}}
|
||||||
|
<source src="{{rewriteURL .url}}" type="video/mp4">
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</video>
|
||||||
|
{{else}}
|
||||||
|
<a href="{{$entity.expanded_url}}" class="media-link">
|
||||||
|
<img src="{{rewriteURL $entity.media_url_https}}" class="media-img">
|
||||||
|
</a>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,6 +10,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -28,9 +30,14 @@ var (
|
||||||
databaseURL = flag.String("database_url", "", "Database URL")
|
databaseURL = flag.String("database_url", "", "Database URL")
|
||||||
userMapping = userMap{}
|
userMapping = userMap{}
|
||||||
localDisableAuth = flag.String("local_auth_override_user", "", "Disable authn/authz - used for dev - set to username")
|
localDisableAuth = flag.String("local_auth_override_user", "", "Disable authn/authz - used for dev - set to username")
|
||||||
|
mediaDirectory = flag.String("media_dir", "/media", "Archived media directory")
|
||||||
|
|
||||||
indexTmpl = template.Must(template.ParseFiles("templates/index.html"))
|
funcMap = template.FuncMap{
|
||||||
tweetsTmpl = template.Must(template.ParseFiles("templates/tweets.html"))
|
"rewriteURL": rewriteURL,
|
||||||
|
"bestVariant": bestVariant,
|
||||||
|
}
|
||||||
|
indexTmpl = template.Must(template.New("index.html").Funcs(funcMap).ParseFiles("templates/index.html"))
|
||||||
|
tweetsTmpl = template.Must(template.New("tweets.html").Funcs(funcMap).ParseFiles("templates/tweets.html"))
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -65,6 +72,34 @@ func (um userMap) Set(v string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func rewriteURL(u string) string {
|
||||||
|
p, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
ps := strings.TrimLeft(p.Path, "/")
|
||||||
|
|
||||||
|
return path.Join("/media", p.Host, ps)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bestVariant(vs []interface{}) interface{} {
|
||||||
|
var bestBitrate float64 = -1
|
||||||
|
var bestVariant interface{}
|
||||||
|
for _, v := range vs {
|
||||||
|
v := v.(map[string]interface{})
|
||||||
|
if v["content_type"].(string) == "application/x-mpegURL" {
|
||||||
|
// m3u8 isn't very interesting since we'd have to parse it to get a playlist.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
br := v["bitrate"].(float64)
|
||||||
|
if br > bestBitrate {
|
||||||
|
bestBitrate = br
|
||||||
|
bestVariant = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestVariant
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -105,6 +140,7 @@ func main() {
|
||||||
fmt.Fprintf(rw, "<p>%s</p>", wrap)
|
fmt.Fprintf(rw, "<p>%s</p>", wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authR.Handle("/media/{path}", http.StripPrefix("/media/", http.FileServer(http.Dir(*mediaDirectory))))
|
||||||
authR.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
|
authR.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
user := userFromContext(ctx)
|
user := userFromContext(ctx)
|
||||||
|
|
Loading…
Reference in a new issue