Compare commits

...

9 Commits

Author SHA1 Message Date
Deluan
35027bbeb8 FIx ffmpeg output regex too rigid 2021-05-05 10:03:14 -04:00
Deluan
3af4677303 Fix cover art detection with ffmpeg 4.4 2021-05-05 10:03:14 -04:00
Deluan
3c30cefc2e Fix warning about promise being ignored 2021-05-05 10:03:14 -04:00
Deluan
d0fea6bffb Fix SIGUSR1 work when ScanInterval=0 2021-05-05 10:01:32 -04:00
Deluan
fff717395c Fix "Failed prop type: Invalid prop variant" in console 2021-05-05 10:01:12 -04:00
Deluan
90a0739251 Fix "SharedArrayBuffer will require cross-origin isolation"
This is a workaround for React v16 while we don't upgrade to v17

See https://github.com/facebook/create-react-app/issues/10474
2021-05-05 10:01:12 -04:00
Samarjeet
ab68524763 [Spotify-ish] Indicate active page number (#1068) 2021-05-05 10:01:12 -04:00
Deluan
125c4fe5ec Keepalive must return an ID to be used with dataProvider.getOne 2021-05-05 10:00:25 -04:00
Deluan
616a44bac4 Fix aspect ratio of login icon 2021-05-05 10:00:25 -04:00
11 changed files with 79 additions and 25 deletions

View File

@@ -53,8 +53,16 @@ func runNavidrome() {
db.EnsureLatestVersion()
var g run.Group
g.Add(startServer())
g.Add(startScanner())
g.Add(startSignaler())
interval := conf.Server.ScanInterval
if interval != 0 {
g.Add(startScanner(interval))
} else {
log.Warn("Periodic scan is DISABLED", "interval", interval)
}
if err := g.Run(); err != nil {
log.Error("Fatal error in Navidrome. Aborting", err)
@@ -76,20 +84,45 @@ func startServer() (func() error, func(err error)) {
}
}
func startScanner() (func() error, func(err error)) {
interval := conf.Server.ScanInterval
var sigChan = make(chan os.Signal, 1)
func startSignaler() (func() error, func(err error)) {
scanner := GetScanner()
ctx, cancel := context.WithCancel(context.Background())
return func() error {
for {
select {
case sig := <-sigChan:
log.Info(ctx, "Received signal, triggering a new scan", "signal", sig)
start := time.Now()
err := scanner.RescanAll(ctx, false)
if err != nil {
log.Error(ctx, "Error scanning", err)
}
log.Info(ctx, "Triggered scan complete", "elapsed", time.Since(start).Round(100*time.Millisecond))
case <-ctx.Done():
break
}
}
}, func(err error) {
cancel()
if err != nil {
log.Error("Shutting down Signaler due to error", err)
} else {
log.Info("Shutting down Signaler")
}
}
}
func startScanner(interval time.Duration) (func() error, func(err error)) {
log.Info("Starting scanner", "interval", interval.String())
scanner := GetScanner()
ctx, cancel := context.WithCancel(context.Background())
return func() error {
if interval != 0 {
time.Sleep(2 * time.Second) // Wait 2 seconds before the first scan
scanner.Run(ctx, interval)
} else {
log.Warn("Periodic scan is DISABLED", "interval", interval)
<-ctx.Done()
}
time.Sleep(2 * time.Second) // Wait 2 seconds before the first scan
scanner.Run(ctx, interval)
return nil
}, func(err error) {

View File

@@ -1,7 +1,7 @@
// +build !windows
// +build !plan9
package scanner
package cmd
import (
"os"

View File

@@ -67,10 +67,10 @@ var (
durationRx = regexp.MustCompile(`^\s\sDuration: ([\d.:]+).*bitrate: (\d+)`)
// Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 192 kb/s
bitRateRx = regexp.MustCompile(`^\s{4}Stream #\d+:\d+: (Audio):.*, (\d+) kb/s`)
bitRateRx = regexp.MustCompile(`^\s{2,4}Stream #\d+:\d+: (Audio):.*, (\d+) kb/s`)
// Stream #0:1: Video: mjpeg, yuvj444p(pc, bt470bg/unknown/unknown), 600x600 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn, 90k tbc`
coverRx = regexp.MustCompile(`^\s{4}Stream #\d+:\d+: (Video):.*`)
coverRx = regexp.MustCompile(`^\s{2,4}Stream #\d+:\d+: (Video):.*`)
)
func (e *ffmpegExtractor) parseOutput(output string) map[string]string {

View File

@@ -92,6 +92,21 @@ Input #0, mp3, from '/Users/deluan/Music/iTunes/iTunes Media/Music/Compilations/
Expect(md.HasPicture()).To(BeTrue())
})
It("detects embedded cover art in ffmpeg 4.4 output", func() {
const output = `
Input #0, flac, from '/run/media/naomi/Archivio/Musica/Katy Perry/Chained to the Rhythm/01 Katy Perry featuring Skip Marley - Chained to the Rhythm.flac':
Metadata:
ARTIST : Katy Perry featuring Skip Marley
Duration: 00:03:57.91, start: 0.000000, bitrate: 983 kb/s
Stream #0:0: Audio: flac, 44100 Hz, stereo, s16
Stream #0:1: Video: mjpeg (Baseline), yuvj444p(pc, bt470bg/unknown/unknown), 599x518, 90k tbr, 90k tbn, 90k tbc (attached pic)
Metadata:
comment : Cover (front)`
md, _ := e.extractMetadata("tests/fixtures/test.mp3", output)
Expect(md.HasPicture()).To(BeTrue())
})
It("detects embedded cover art in ogg containers", func() {
const output = `
Input #0, ogg, from '/Users/deluan/Music/iTunes/iTunes Media/Music/_Testes/Jamaican In New York/01-02 Jamaican In New York (Album Version).opus':

View File

@@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"os"
"strconv"
"sync"
"time"
@@ -40,10 +39,7 @@ type FolderScanner interface {
Scan(ctx context.Context, lastModifiedSince time.Time, progress chan uint32) error
}
var (
isScanning utils.AtomicBool
sigChan = make(chan os.Signal, 1)
)
var isScanning utils.AtomicBool
type scanner struct {
folders map[string]FolderScanner
@@ -87,9 +83,6 @@ func (s *scanner) Run(ctx context.Context, interval time.Duration) {
select {
case <-ticker.C:
continue
case sig := <-sigChan:
log.Info(ctx, "Received signal, triggering a new scan", "signal", sig)
continue
case <-ctx.Done():
return
}

View File

@@ -69,7 +69,9 @@ func (app *Router) routes(path string) http.Handler {
app.addPlaylistTrackRoute(r)
// Keepalive endpoint to be used to keep the session valid (ex: while playing songs)
r.Get("/keepalive/*", func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(`{"response":"ok"}`)) })
r.Get("/keepalive/*", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(`{"response":"ok", "id":"keepalive"}`))
})
if conf.Server.DevActivityPanel {
r.Handle("/events", app.broker)

View File

@@ -33,6 +33,11 @@
<script>
window.__APP_CONFIG__ = "{{.AppConfig}}"
</script>
<!-- Issue workaround for React v16. -->
<script>
// See https://github.com/facebook/react/issues/20829#issuecomment-802088260
if (!crossOriginIsolated) SharedArrayBuffer = ArrayBuffer;
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

View File

@@ -67,8 +67,9 @@ const SelectLanguage = (props) => {
openInNewTab(docsUrl('/docs/developers/translations/'))
return
}
setLocale(event.target.value)
localStorage.setItem('locale', event.target.value)
setLocale(event.target.value).then(() => {
localStorage.setItem('locale', event.target.value)
})
}}
/>
)

View File

@@ -12,7 +12,7 @@ import {
} from 'react-admin'
import { Title } from '../common'
const SyncFragment = ({ formData, ...rest }) => {
const SyncFragment = ({ formData, variant, ...rest }) => {
return (
<Fragment>
{formData.path && <BooleanInput source="sync" {...rest} />}

View File

@@ -346,6 +346,7 @@ export default {
icon: {
backgroundColor: 'transparent',
width: '100px',
height: '100px',
},
card: {
minWidth: 300,

View File

@@ -267,6 +267,7 @@ export default {
icon: {
backgroundColor: 'inherit',
width: '5em',
height: '5em',
},
card: {
background: 'none',
@@ -306,6 +307,9 @@ export default {
},
},
RaPaginationActions: {
currentPageButton: {
border: '1px solid #b3b3b3',
},
button: {
backgroundColor: 'inherit',
minWidth: 48,