move transcoding stuff to "encode" package
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package ctrlsubsonic
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
@@ -9,10 +11,31 @@ import (
|
||||
|
||||
"senan.xyz/g/gonic/db"
|
||||
"senan.xyz/g/gonic/mime"
|
||||
"senan.xyz/g/gonic/server/ctrlsubsonic/encode"
|
||||
"senan.xyz/g/gonic/server/ctrlsubsonic/params"
|
||||
"senan.xyz/g/gonic/server/ctrlsubsonic/spec"
|
||||
)
|
||||
|
||||
// Put special clients that can't handle Opus here:
|
||||
func encodeProfileFor(client string) string {
|
||||
switch client {
|
||||
case "Soundwaves":
|
||||
return "mp3_rg"
|
||||
case "Jamstash":
|
||||
return "opus_rg"
|
||||
default:
|
||||
return "opus"
|
||||
}
|
||||
}
|
||||
|
||||
func fileExists(filename string) bool {
|
||||
info, err := os.Stat(filename)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
// "raw" handlers are ones that don't always return a spec response.
|
||||
// it could be a file, stream, etc. so you must either
|
||||
// a) write to response writer
|
||||
@@ -60,11 +83,23 @@ func (c *Controller) ServeStream(w http.ResponseWriter, r *http.Request) *spec.R
|
||||
if gorm.IsRecordNotFoundError(err) {
|
||||
return spec.NewError(70, "media with id `%d` was not found", id)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
user := r.Context().Value(CtxUser).(*model.User)
|
||||
play := model.Play{
|
||||
AlbumID: track.Album.ID,
|
||||
UserID: user.ID,
|
||||
}
|
||||
c.DB.
|
||||
Where(play).
|
||||
First(&play)
|
||||
play.Time = time.Now() // for getAlbumList?type=recent
|
||||
play.Count++ // for getAlbumList?type=frequent
|
||||
c.DB.Save(&play)
|
||||
}()
|
||||
client := params.GetOr("c", "generic")
|
||||
bitrate, err := params.GetInt("maxBitRate")
|
||||
maxBitrate, err := params.GetInt("maxBitRate")
|
||||
if err != nil {
|
||||
bitrate = 0
|
||||
maxBitrate = 0
|
||||
}
|
||||
|
||||
absPath := path.Join(
|
||||
@@ -73,21 +108,19 @@ func (c *Controller) ServeStream(w http.ResponseWriter, r *http.Request) *spec.R
|
||||
track.Album.RightPath,
|
||||
track.Filename,
|
||||
)
|
||||
streamTrack(w, r, absPath, client, bitrate, c.CachePath)
|
||||
|
||||
//
|
||||
// after we've served the file, mark the album as played
|
||||
user := r.Context().Value(CtxUser).(*db.User)
|
||||
play := db.Play{
|
||||
AlbumID: track.Album.ID,
|
||||
UserID: user.ID,
|
||||
profileName := encodeProfileFor(client)
|
||||
profile := encode.Profiles[profileName]
|
||||
bitrate := encode.GetBitrate(maxBitrate, profile)
|
||||
cacheKey := encode.CacheKey(absPath, profileName, bitrate)
|
||||
cacheFile := path.Join(c.CachePath, cacheKey)
|
||||
if fileExists(cacheFile) {
|
||||
log.Printf("cache [%s/%s] hit!\n", profile.Format, bitrate)
|
||||
http.ServeFile(w, r, cacheFile)
|
||||
return
|
||||
}
|
||||
if err := encode.Encode(w, absPath, cacheFile, profile, bitrate); err != nil {
|
||||
log.Printf("cache [%s/%s] miss!\n", profile.Format, bitrate)
|
||||
}
|
||||
c.DB.
|
||||
Where(play).
|
||||
First(&play)
|
||||
play.Time = time.Now() // for getAlbumList?type=recent
|
||||
play.Count++ // for getAlbumList?type=frequent
|
||||
c.DB.Save(&play)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user