mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-03 04:27:37 +03:00
Use wchar_t for TagLib filenames on Windows (#1310)
* Use wchar_t for tagLib filenames on Windows * Make TagLib default extractor for all platforms. * Organize imports Co-authored-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
c55e65902b
commit
54f98497c2
10 changed files with 122 additions and 18 deletions
|
@ -214,7 +214,7 @@ func init() {
|
|||
viper.SetDefault("reverseproxyuserheader", "Remote-User")
|
||||
viper.SetDefault("reverseproxywhitelist", "")
|
||||
|
||||
viper.SetDefault("scanner.extractor", DefaultScannerExtractor)
|
||||
viper.SetDefault("scanner.extractor", consts.DefaultScannerExtractor)
|
||||
viper.SetDefault("scanner.genreseparators", ";/,")
|
||||
|
||||
viper.SetDefault("agents", "lastfm,spotify")
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
// +build !windows
|
||||
|
||||
package conf
|
||||
|
||||
const DefaultScannerExtractor = "taglib"
|
|
@ -1,5 +0,0 @@
|
|||
// +build windows
|
||||
|
||||
package conf
|
||||
|
||||
const DefaultScannerExtractor = "ffmpeg"
|
|
@ -47,6 +47,8 @@ const (
|
|||
PlaceholderAvatar = "logo-192x192.png"
|
||||
|
||||
DefaultHttpClientTimeOut = 10 * time.Second
|
||||
|
||||
DefaultScannerExtractor = "taglib"
|
||||
)
|
||||
|
||||
// Cache options
|
||||
|
|
|
@ -10,13 +10,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/navidrome/navidrome/scanner/metadata/ffmpeg"
|
||||
|
||||
"github.com/navidrome/navidrome/scanner/metadata/taglib"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/navidrome/navidrome/conf"
|
||||
"github.com/navidrome/navidrome/consts"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/scanner/metadata/ffmpeg"
|
||||
"github.com/navidrome/navidrome/scanner/metadata/taglib"
|
||||
)
|
||||
|
||||
type Parser interface {
|
||||
|
@ -32,8 +31,8 @@ func Extract(files ...string) (map[string]Tags, error) {
|
|||
p, ok := parsers[conf.Server.Scanner.Extractor]
|
||||
if !ok {
|
||||
log.Warn("Invalid 'Scanner.Extractor' option. Using default", "requested", conf.Server.Scanner.Extractor,
|
||||
"validOptions", "ffmpeg,taglib", "default", conf.DefaultScannerExtractor)
|
||||
p = parsers[conf.DefaultScannerExtractor]
|
||||
"validOptions", "ffmpeg,taglib", "default", consts.DefaultScannerExtractor)
|
||||
p = parsers[consts.DefaultScannerExtractor]
|
||||
}
|
||||
|
||||
extractedTags, err := p.Parse(files...)
|
||||
|
|
9
scanner/metadata/taglib/get_filename.go
Normal file
9
scanner/metadata/taglib/get_filename.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
// +build !windows
|
||||
|
||||
package taglib
|
||||
|
||||
import "C"
|
||||
|
||||
func getFilename(s string) *C.char {
|
||||
return C.CString(s)
|
||||
}
|
96
scanner/metadata/taglib/get_filename_win.go
Normal file
96
scanner/metadata/taglib/get_filename_win.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
// +build windows
|
||||
|
||||
package taglib
|
||||
|
||||
// From https://github.com/orofarne/gowchar
|
||||
|
||||
/*
|
||||
#include <wchar.h>
|
||||
|
||||
const size_t SIZEOF_WCHAR_T = sizeof(wchar_t);
|
||||
|
||||
void gowchar_set (wchar_t *arr, int pos, wchar_t val)
|
||||
{
|
||||
arr[pos] = val;
|
||||
}
|
||||
|
||||
wchar_t gowchar_get (wchar_t *arr, int pos)
|
||||
{
|
||||
return arr[pos];
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode/utf16"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var SIZEOF_WCHAR_T C.size_t = C.size_t(C.SIZEOF_WCHAR_T)
|
||||
|
||||
func getFilename(s string) *C.wchar_t {
|
||||
wstr, _ := StringToWcharT(s)
|
||||
return wstr
|
||||
}
|
||||
|
||||
func StringToWcharT(s string) (*C.wchar_t, C.size_t) {
|
||||
switch SIZEOF_WCHAR_T {
|
||||
case 2:
|
||||
return stringToWchar2(s) // Windows
|
||||
case 4:
|
||||
return stringToWchar4(s) // Unix
|
||||
default:
|
||||
panic(fmt.Sprintf("Invalid sizeof(wchar_t) = %v", SIZEOF_WCHAR_T))
|
||||
}
|
||||
panic("?!!")
|
||||
}
|
||||
|
||||
// Windows
|
||||
func stringToWchar2(s string) (*C.wchar_t, C.size_t) {
|
||||
var slen int
|
||||
s1 := s
|
||||
for len(s1) > 0 {
|
||||
r, size := utf8.DecodeRuneInString(s1)
|
||||
if er, _ := utf16.EncodeRune(r); er == '\uFFFD' {
|
||||
slen += 1
|
||||
} else {
|
||||
slen += 2
|
||||
}
|
||||
s1 = s1[size:]
|
||||
}
|
||||
slen++ // \0
|
||||
res := C.malloc(C.size_t(slen) * SIZEOF_WCHAR_T)
|
||||
var i int
|
||||
for len(s) > 0 {
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
if r1, r2 := utf16.EncodeRune(r); r1 != '\uFFFD' {
|
||||
C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r1))
|
||||
i++
|
||||
C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r2))
|
||||
i++
|
||||
} else {
|
||||
C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r))
|
||||
i++
|
||||
}
|
||||
s = s[size:]
|
||||
}
|
||||
C.gowchar_set((*C.wchar_t)(res), C.int(slen-1), C.wchar_t(0)) // \0
|
||||
return (*C.wchar_t)(res), C.size_t(slen)
|
||||
}
|
||||
|
||||
// Unix
|
||||
func stringToWchar4(s string) (*C.wchar_t, C.size_t) {
|
||||
slen := utf8.RuneCountInString(s)
|
||||
slen++ // \0
|
||||
res := C.malloc(C.size_t(slen) * SIZEOF_WCHAR_T)
|
||||
var i int
|
||||
for len(s) > 0 {
|
||||
r, size := utf8.DecodeRuneInString(s)
|
||||
C.gowchar_set((*C.wchar_t)(res), C.int(i), C.wchar_t(r))
|
||||
s = s[size:]
|
||||
i++
|
||||
}
|
||||
C.gowchar_set((*C.wchar_t)(res), C.int(slen-1), C.wchar_t(0)) // \0
|
||||
return (*C.wchar_t)(res), C.size_t(slen)
|
||||
}
|
|
@ -17,7 +17,11 @@
|
|||
|
||||
char has_cover(const TagLib::FileRef f);
|
||||
|
||||
#ifdef WIN32
|
||||
int taglib_read(const wchar_t *filename, unsigned long id) {
|
||||
#else
|
||||
int taglib_read(const char *filename, unsigned long id) {
|
||||
#endif
|
||||
TagLib::FileRef f(filename, true, TagLib::AudioProperties::Fast);
|
||||
|
||||
if (f.isNull()) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
)
|
||||
|
||||
func Read(filename string) (map[string][]string, error) {
|
||||
fp := C.CString(filename)
|
||||
fp := getFilename(filename)
|
||||
defer C.free(unsafe.Pointer(fp))
|
||||
id, m := newMap()
|
||||
defer deleteMap(id)
|
||||
|
|
|
@ -8,7 +8,11 @@ extern "C" {
|
|||
extern void go_map_put_str(unsigned long id, char *key, char *val);
|
||||
extern void go_map_put_int(unsigned long id, char *key, int val);
|
||||
|
||||
#ifdef WIN32
|
||||
int taglib_read(const wchar_t *filename, unsigned long id);
|
||||
#else
|
||||
int taglib_read(const char *filename, unsigned long id);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue