fix(subsonic): send valid content-type with http.ServeStream
This commit is contained in:
21
db/model.go
21
db/model.go
@@ -8,13 +8,14 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
// TODO: remove this dep
|
|
||||||
|
|
||||||
"go.senan.xyz/gonic/mime"
|
"go.senan.xyz/gonic/mime"
|
||||||
|
|
||||||
|
// TODO: remove this dep
|
||||||
"go.senan.xyz/gonic/server/ctrlsubsonic/specid"
|
"go.senan.xyz/gonic/server/ctrlsubsonic/specid"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -123,11 +124,7 @@ func (t *Track) ArtistSID() *specid.ID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Track) Ext() string {
|
func (t *Track) Ext() string {
|
||||||
longExt := path.Ext(t.Filename)
|
return filepath.Ext(t.Filename)
|
||||||
if len(longExt) < 1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return longExt[1:]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Track) AudioFilename() string {
|
func (t *Track) AudioFilename() string {
|
||||||
@@ -135,7 +132,7 @@ func (t *Track) AudioFilename() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Track) MIME() string {
|
func (t *Track) MIME() string {
|
||||||
return mime.FromExtension(t.Ext())
|
return mime.TypeByExtension(filepath.Ext(t.Filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Track) AbsPath() string {
|
func (t *Track) AbsPath() string {
|
||||||
@@ -419,15 +416,11 @@ func (pe *PodcastEpisode) AudioFilename() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pe *PodcastEpisode) Ext() string {
|
func (pe *PodcastEpisode) Ext() string {
|
||||||
longExt := path.Ext(pe.Filename)
|
return filepath.Ext(pe.Filename)
|
||||||
if len(longExt) < 1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return longExt[1:]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe *PodcastEpisode) MIME() string {
|
func (pe *PodcastEpisode) MIME() string {
|
||||||
return mime.FromExtension(pe.Ext())
|
return mime.TypeByExtension(filepath.Ext(pe.Filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bookmark struct {
|
type Bookmark struct {
|
||||||
|
|||||||
54
mime/mime.go
54
mime/mime.go
@@ -1,24 +1,38 @@
|
|||||||
|
//nolint:gochecknoglobals
|
||||||
package mime
|
package mime
|
||||||
|
|
||||||
func FromExtension(ext string) string {
|
import (
|
||||||
switch ext {
|
"log"
|
||||||
case "mp3":
|
stdmime "mime"
|
||||||
return "audio/mpeg"
|
)
|
||||||
case "flac":
|
|
||||||
return "audio/x-flac"
|
var supportedAudioTypes = map[string]string{
|
||||||
case "aac":
|
".mp3": "audio/mpeg",
|
||||||
return "audio/x-aac"
|
".flac": "audio/x-flac",
|
||||||
case "m4a":
|
".aac": "audio/x-aac",
|
||||||
return "audio/m4a"
|
".m4a": "audio/m4a",
|
||||||
case "m4b":
|
".m4b": "audio/m4b",
|
||||||
return "audio/m4b"
|
".ogg": "audio/ogg",
|
||||||
case "ogg":
|
".opus": "audio/ogg",
|
||||||
return "audio/ogg"
|
".wma": "audio/x-ms-wma",
|
||||||
case "opus":
|
}
|
||||||
return "audio/ogg"
|
|
||||||
case "wma":
|
//nolint:gochecknoinits
|
||||||
return "audio/x-ms-wma"
|
func init() {
|
||||||
default:
|
for ext, mime := range supportedAudioTypes {
|
||||||
return ""
|
if err := stdmime.AddExtensionType(ext, mime); err != nil {
|
||||||
|
log.Fatalf("adding audio type mime for ext %q: %v", ext, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TypeByExtension = stdmime.TypeByExtension
|
||||||
|
var ParseMediaType = stdmime.ParseMediaType
|
||||||
|
var FormatMediaType = stdmime.FormatMediaType
|
||||||
|
|
||||||
|
func TypeByAudioExtension(ext string) string {
|
||||||
|
if _, ok := supportedAudioTypes[ext]; !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return stdmime.TypeByExtension(ext)
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"mime"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -19,7 +18,7 @@ import (
|
|||||||
"github.com/mmcdole/gofeed"
|
"github.com/mmcdole/gofeed"
|
||||||
|
|
||||||
"go.senan.xyz/gonic/db"
|
"go.senan.xyz/gonic/db"
|
||||||
gmime "go.senan.xyz/gonic/mime"
|
"go.senan.xyz/gonic/mime"
|
||||||
"go.senan.xyz/gonic/multierr"
|
"go.senan.xyz/gonic/multierr"
|
||||||
"go.senan.xyz/gonic/scanner/tags"
|
"go.senan.xyz/gonic/scanner/tags"
|
||||||
)
|
)
|
||||||
@@ -236,10 +235,7 @@ func (p *Podcasts) AddEpisode(podcastID int, item *gofeed.Item) (*db.PodcastEpis
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isAudio(mediaType, url string) bool {
|
func isAudio(mediaType, url string) bool {
|
||||||
if mediaType != "" && strings.HasPrefix(mediaType, "audio") {
|
return mime.TypeByAudioExtension(path.Ext(url)) != ""
|
||||||
return true
|
|
||||||
}
|
|
||||||
return gmime.FromExtension(filepath.Ext(url)[1:]) != ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func itemToEpisode(podcastID, size, duration int, audio string,
|
func itemToEpisode(podcastID, size, duration int, audio string,
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ func (s *Scanner) scanDir(tx *db.DB, c *Context, musicDir string, absPath string
|
|||||||
cover = item.Name()
|
cover = item.Name()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if mime := mime.FromExtension(ext(item.Name())); mime != "" {
|
if mime := mime.TypeByAudioExtension(filepath.Ext(item.Name())); mime != "" {
|
||||||
tracks = append(tracks, item.Name())
|
tracks = append(tracks, item.Name())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -578,13 +578,6 @@ func (s *Scanner) cleanGenres(c *Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ext(name string) string {
|
|
||||||
if ext := filepath.Ext(name); len(ext) > 0 {
|
|
||||||
return ext[1:]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func isCover(name string) bool {
|
func isCover(name string) bool {
|
||||||
switch path := strings.ToLower(name); path {
|
switch path := strings.ToLower(name); path {
|
||||||
case
|
case
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ func NewTCTrackByFolder(t *db.Track, parent *db.Album) *TrackChild {
|
|||||||
trCh := &TrackChild{
|
trCh := &TrackChild{
|
||||||
ID: t.SID(),
|
ID: t.SID(),
|
||||||
ContentType: t.MIME(),
|
ContentType: t.MIME(),
|
||||||
Suffix: t.Ext(),
|
Suffix: formatExt(t.Ext()),
|
||||||
Size: t.Size,
|
Size: t.Size,
|
||||||
Artist: t.TagTrackArtist,
|
Artist: t.TagTrackArtist,
|
||||||
Title: t.TagTitle,
|
Title: t.TagTitle,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func NewTrackByTags(t *db.Track, album *db.Album) *TrackChild {
|
|||||||
ret := &TrackChild{
|
ret := &TrackChild{
|
||||||
ID: t.SID(),
|
ID: t.SID(),
|
||||||
ContentType: t.MIME(),
|
ContentType: t.MIME(),
|
||||||
Suffix: t.Ext(),
|
Suffix: formatExt(t.Ext()),
|
||||||
ParentID: t.AlbumSID(),
|
ParentID: t.AlbumSID(),
|
||||||
CreatedAt: t.CreatedAt,
|
CreatedAt: t.CreatedAt,
|
||||||
Size: t.Size,
|
Size: t.Size,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func NewPodcastEpisode(e *db.PodcastEpisode) *PodcastEpisode {
|
|||||||
Genre: "Podcast",
|
Genre: "Podcast",
|
||||||
Duration: e.Length,
|
Duration: e.Length,
|
||||||
Year: e.PublishDate.Year(),
|
Year: e.PublishDate.Year(),
|
||||||
Suffix: e.Ext(),
|
Suffix: formatExt(e.Ext()),
|
||||||
BitRate: e.Bitrate,
|
BitRate: e.Bitrate,
|
||||||
IsDir: false,
|
IsDir: false,
|
||||||
Path: e.Path,
|
Path: e.Path,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package spec
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.senan.xyz/gonic"
|
"go.senan.xyz/gonic"
|
||||||
@@ -422,3 +423,7 @@ func formatRating(rating float64) string {
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("%.2f", rating)
|
return fmt.Sprintf("%.2f", rating)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatExt(ext string) string {
|
||||||
|
return strings.TrimPrefix(ext, ".")
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user