Added audio file support

This commit is contained in:
Seednode 2023-09-10 21:02:03 -05:00
parent 8d0d271f79
commit 32bd20522a
4 changed files with 54 additions and 14 deletions

View File

@ -8,7 +8,7 @@ A new file will be selected if you open `/` directly, or if you click on any dis
Browser history is preserved, so you can always go back to any previously displayed media. Browser history is preserved, so you can always go back to any previously displayed media.
Supported file types and extensions are `bmp`, `gif`, `jp[e]g`, `png`, `webp`, `mp4`, `ogv`, `webm`. Supported file types and extensions are `bmp`, `gif`, `jp[e]g`, `m4a`, `mp3`, `mp4`, `.ogg`, `.ogv`, `png`, `wav`, `webm`, `webp`.
Feature requests, code criticism, bug reports, general chit-chat, and unrelated angst accepted at `roulette@seedno.de`. Feature requests, code criticism, bug reports, general chit-chat, and unrelated angst accepted at `roulette@seedno.de`.

View File

@ -44,7 +44,20 @@ type Concurrency struct {
var ( var (
ErrNoMediaFound = errors.New("no supported media formats found which match all criteria") ErrNoMediaFound = errors.New("no supported media formats found which match all criteria")
Extensions = [9]string{".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".mp4", ".ogv", ".webm"} Extensions = [12]string{
".bmp",
".gif",
".jpeg",
".jpg",
".mp3",
".mp4",
".ogg",
".ogv",
".png",
".wav",
".webm",
".webp",
}
) )
type Dimensions struct { type Dimensions struct {
@ -144,7 +157,7 @@ func preparePath(path string) string {
func appendPath(directory, path string, files *Files, stats *ScanStats, shouldCache bool) error { func appendPath(directory, path string, files *Files, stats *ScanStats, shouldCache bool) error {
if shouldCache { if shouldCache {
supported, _, _, err := isSupportedFileType(path) supported, _, _, err := fileType(path)
if err != nil { if err != nil {
return err return err
} }
@ -358,7 +371,7 @@ func pathIsValid(filePath string, paths []string) bool {
} }
} }
func isSupportedFileType(path string) (bool, string, string, error) { func fileType(path string) (bool, string, string, error) {
file, err := os.Open(path) file, err := os.Open(path)
switch { switch {
case errors.Is(err, os.ErrNotExist): case errors.Is(err, os.ErrNotExist):
@ -371,14 +384,30 @@ func isSupportedFileType(path string) (bool, string, string, error) {
head := make([]byte, 261) head := make([]byte, 261)
file.Read(head) file.Read(head)
extension := strings.TrimPrefix(filepath.Ext(path), ".") extension := filepath.Ext(path)
fileType := filetype.GetType(extension) isSupported := false
for _, e := range Extensions {
if e == extension {
isSupported = true
break
}
}
if !isSupported {
return false, "", "", nil
}
fileType := filetype.GetType(strings.TrimPrefix(extension, "."))
switch { switch {
case filetype.IsAudio(head) && audio:
return true, "audio", fileType.MIME.Value, nil
case filetype.IsImage(head): case filetype.IsImage(head):
return true, "image", fileType.MIME.Value, nil return true, "image", fileType.MIME.Value, nil
case filetype.IsVideo(head): case filetype.IsVideo(head) && video:
return true, "video", fileType.MIME.Value, nil return true, "video", fileType.MIME.Value, nil
default: default:
return false, "", "", nil return false, "", "", nil
@ -397,7 +426,7 @@ func pathHasSupportedFiles(path string) (bool, error) {
case !recursive && info.IsDir() && p != path: case !recursive && info.IsDir() && p != path:
return filepath.SkipDir return filepath.SkipDir
case !info.IsDir(): case !info.IsDir():
supported, _, _, err := isSupportedFileType(p) supported, _, _, err := fileType(p)
if err != nil { if err != nil {
return err return err
} }
@ -645,7 +674,7 @@ func pickFile(args []string, filters *Filters, sort string, index *Index) (strin
filePath := fileList[val] filePath := fileList[val]
if !fromCache { if !fromCache {
supported, _, _, err := isSupportedFileType(filePath) supported, _, _, err := fileType(filePath)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@ -17,10 +17,11 @@ var (
) )
const ( const (
Version string = "0.61.2" Version string = "0.62.0"
) )
var ( var (
audio bool
bind string bind string
cache bool cache bool
cacheFile string cacheFile string
@ -39,6 +40,7 @@ var (
statisticsFile string statisticsFile string
verbose bool verbose bool
version bool version bool
video bool
rootCmd = &cobra.Command{ rootCmd = &cobra.Command{
Use: "roulette <path> [path]...", Use: "roulette <path> [path]...",
@ -75,6 +77,7 @@ func Execute() {
} }
func init() { func init() {
rootCmd.Flags().BoolVar(&audio, "audio", false, "additionally support audio files")
rootCmd.Flags().StringVarP(&bind, "bind", "b", "0.0.0.0", "address to bind to") rootCmd.Flags().StringVarP(&bind, "bind", "b", "0.0.0.0", "address to bind to")
rootCmd.Flags().BoolVarP(&cache, "cache", "c", false, "generate directory cache at startup") rootCmd.Flags().BoolVarP(&cache, "cache", "c", false, "generate directory cache at startup")
rootCmd.Flags().StringVar(&cacheFile, "cache-file", "", "path to optional persistent cache file") rootCmd.Flags().StringVar(&cacheFile, "cache-file", "", "path to optional persistent cache file")
@ -93,6 +96,8 @@ func init() {
rootCmd.Flags().StringVar(&statisticsFile, "stats-file", "", "path to optional persistent stats file") rootCmd.Flags().StringVar(&statisticsFile, "stats-file", "", "path to optional persistent stats file")
rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "log accessed files to stdout") rootCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "log accessed files to stdout")
rootCmd.Flags().BoolVarP(&version, "version", "V", false, "display version and exit") rootCmd.Flags().BoolVarP(&version, "version", "V", false, "display version and exit")
rootCmd.Flags().BoolVar(&video, "video", false, "additionally support video files")
rootCmd.Flags().SetInterspersed(true) rootCmd.Flags().SetInterspersed(true)
rootCmd.CompletionOptions.HiddenDefaultCmd = true rootCmd.CompletionOptions.HiddenDefaultCmd = true

View File

@ -974,7 +974,7 @@ func serveMedia(paths []string, Regexes *Regexes, index *Index) httprouter.Handl
return return
} }
supported, fileType, mime, err := isSupportedFileType(filePath) supported, fileType, mime, err := fileType(filePath)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -1020,7 +1020,7 @@ func serveMedia(paths []string, Regexes *Regexes, index *Index) httprouter.Handl
fileName, fileName,
dimensions.width, dimensions.width,
dimensions.height)) dimensions.height))
case "video": default:
htmlBody.WriteString(fmt.Sprintf(`<title>%s</title>`, htmlBody.WriteString(fmt.Sprintf(`<title>%s</title>`,
fileName)) fileName))
} }
@ -1033,6 +1033,12 @@ func serveMedia(paths []string, Regexes *Regexes, index *Index) httprouter.Handl
} }
switch fileType { switch fileType {
case "audio":
htmlBody.WriteString(fmt.Sprintf(`<a href="/%s"><audio controls autoplay><source src="%s" type="%s" alt="Roulette selected: %s">Your browser does not support the audio tag.</audio></a>`,
queryParams,
generateFilePath(filePath),
mime,
fileName))
case "image": case "image":
htmlBody.WriteString(fmt.Sprintf(`<a href="/%s"><img src="%s" width="%d" height="%d" type="%s" alt="Roulette selected: %s"></a>`, htmlBody.WriteString(fmt.Sprintf(`<a href="/%s"><img src="%s" width="%d" height="%d" type="%s" alt="Roulette selected: %s"></a>`,
queryParams, queryParams,
@ -1041,16 +1047,16 @@ func serveMedia(paths []string, Regexes *Regexes, index *Index) httprouter.Handl
dimensions.height, dimensions.height,
mime, mime,
fileName)) fileName))
htmlBody.WriteString(`</body></html>`)
case "video": case "video":
htmlBody.WriteString(fmt.Sprintf(`<a href="/%s"><video controls autoplay><source src="%s" type="%s" alt="Roulette selected: %s">Your browser does not support the video tag.</video></a>`, htmlBody.WriteString(fmt.Sprintf(`<a href="/%s"><video controls autoplay><source src="%s" type="%s" alt="Roulette selected: %s">Your browser does not support the video tag.</video></a>`,
queryParams, queryParams,
generateFilePath(filePath), generateFilePath(filePath),
mime, mime,
fileName)) fileName))
htmlBody.WriteString(`</body></html>`)
} }
htmlBody.WriteString(`</body></html>`)
_, err = io.WriteString(w, gohtml.Format(htmlBody.String())) _, err = io.WriteString(w, gohtml.Format(htmlBody.String()))
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)