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%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.media-video {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<h1>Twitterchiver: {{.TwitterUsername}}</h1>
|
||||
{{if .Query}}
|
||||
|
@ -141,9 +144,19 @@ a:hover {
|
|||
<div class="media">
|
||||
{{range $entity := .Object.extended_entities.media}}
|
||||
<div class="media-item">
|
||||
{{if eq $entity.type "video"}}
|
||||
<video controls poster="{{rewriteURL $entity.media_url_https}}" class="media-video">
|
||||
{{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="{{$entity.media_url_https}}" class="media-img">
|
||||
<img src="{{rewriteURL $entity.media_url_https}}" class="media-img">
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -28,9 +30,14 @@ var (
|
|||
databaseURL = flag.String("database_url", "", "Database URL")
|
||||
userMapping = userMap{}
|
||||
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"))
|
||||
tweetsTmpl = template.Must(template.ParseFiles("templates/tweets.html"))
|
||||
funcMap = template.FuncMap{
|
||||
"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() {
|
||||
|
@ -65,6 +72,34 @@ func (um userMap) Set(v string) error {
|
|||
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() {
|
||||
flag.Parse()
|
||||
ctx := context.Background()
|
||||
|
@ -105,6 +140,7 @@ func main() {
|
|||
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) {
|
||||
ctx := r.Context()
|
||||
user := userFromContext(ctx)
|
||||
|
|
Loading…
Reference in a new issue