Files

1 line
84 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "allan10w/framebridge", "files": {"pkg/tools/tts_client_test.go": {"7a76c7b491d563e88aa452b5bc774be26e4fbecd": {"t": 1785746068.00991, "n": 4933, "h": "feb538bc4a10122f", "c": "package tools\n\nimport (\n\t\"testing\"\n\n\tappconfig \"github.com/difyz9/ytb2bili/internal/config\"\n\t\"go.uber.org/zap\"\n)\n\nfunc TestBuildRuntimeTTSConfigUsesAzureSection(t *testing.T) {\n\tcfg := &appconfig.AppConfig{\n\t\tLLM: appconfig.LLMConfig{\n\t\t\tBaseURL: \"https://api.deepseek.com\",\n\t\t\tAPIKey: \"sk-test\",\n\t\t},\n\t\tTTS: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t},\n\t\tAzureTTS: appconfig.AzureTTSConfig{\n\t\t\tSubscriptionKey: \"azure-subscription\",\n\t\t\tRegion: \"eastasia\",\n\t\t},\n\t\tTencentTTS: appconfig.TencentTTSConfig{\n\t\t\tSecretID: \"tencent-secret-id\",\n\t\t\tSecretKey: \"tencent-secret-key\",\n\t\t\tRegion: \"ap-guangzhou\",\n\t\t},\n\t}\n\n\truntimeCfg := buildRuntimeTTSConfig(cfg)\n\tif runtimeCfg.AzureSubscriptionKey != \"azure-subscription\" {\n\t\tt.Fatalf(\"expected azure subscription key to be loaded, got %q\", runtimeCfg.AzureSubscriptionKey)\n\t}\n\tif runtimeCfg.AzureRegion != \"eastasia\" {\n\t\tt.Fatalf(\"expected azure region to be loaded, got %q\", runtimeCfg.AzureRegion)\n\t}\n\tif runtimeCfg.TencentSecretID != \"tencent-secret-id\" || runtimeCfg.TencentSecretKey != \"tencent-secret-key\" {\n\t\tt.Fatalf(\"expected Tencent credentials to be loaded\")\n\t}\n\tif runtimeCfg.TencentRegion != \"ap-guangzhou\" {\n\t\tt.Fatalf(\"expected Tencent region to be loaded, got %q\", runtimeCfg.TencentRegion)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_LegacyVoiceValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(\"zh-CN-YunxiNeural\")\n\tif !ok {\n\t\tt.Fatal(\"expected legacy voice value to be parsed\")\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice to be parsed, got %q\", config.Voice)\n\t}\n\tif config.Provider != \"\" {\n\t\tt.Fatalf(\"expected provider to remain empty, got %q\", config.Provider)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_JSONValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(`{\"provider\":\"tencent\",\"voice_name\":\"zh-CN-YunxiNeural\",\"language\":\"zh-CN\",\"format\":\"mp3\",\"search\":\"Yunxi\",\"rate\":1.25,\"volume\":88,\"pitch\":3,\"timeout_seconds\":45}`)\n\tif !ok {\n\t\tt.Fatal(\"expected json config to be parsed\")\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider from json, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice from json, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search from json, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format from json, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate from json, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume from json, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch from json, got %v\", config.Pitch)\n\t}\n\tif config.TimeoutSeconds != 45 {\n\t\tt.Fatalf(\"expected timeout from json, got %v\", config.TimeoutSeconds)\n\t}\n}\n\nfunc TestMergeConfig_UsesUserOverridesAndKeepsGlobalCredentials(t *testing.T) {\n\tclient := newTTSClientWithConfig(TTSConfig{\n\t\tBaseURL: \"https://open.ytb2bili.com\",\n\t\tAPIKey: \"sk-test\",\n\t\tProjectID: \"project-default\",\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t\tFormat: \"audio-24khz-96kbitrate-mono-mp3\",\n\t\t\tRate: 1,\n\t\t\tVolume: 100,\n\t\t},\n\t}, nil, zap.NewNop())\n\n\tconfig := client.mergeConfig(client.config, TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"tencent\",\n\t\t\tVoice: \"zh-CN-YunxiNeural\",\n\t\t\tSearch: \"Yunxi\",\n\t\t\tFormat: \"mp3\",\n\t\t\tRate: 1.25,\n\t\t\tVolume: 88,\n\t\t\tPitch: 3,\n\t\t},\n\t})\n\tif config.BaseURL != \"https://open.ytb2bili.com\" {\n\t\tt.Fatalf(\"expected baseURL to stay global, got %q\", config.BaseURL)\n\t}\n\tif config.APIKey != \"sk-test\" {\n\t\tt.Fatalf(\"expected apiKey to stay global, got %q\", config.APIKey)\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider override, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice override, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search override, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format override, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate override, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume override, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch override, got %v\", config.Pitch)\n\t}\n}\n\nfunc TestNormalizeTTSConfig_ClampsVolumeIntoSupportedRange(t *testing.T) {\n\tconfig := normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: 250,\n\t\t},\n\t})\n\tif config.Volume != 100 {\n\t\tt.Fatalf(\"expected volume to be clamped to 100, got %v\", config.Volume)\n\t}\n\n\tconfig = normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: -15,\n\t\t},\n\t})\n\tif config.Volume != 0 {\n\t\tt.Fatalf(\"expected negative volume to be clamped to 0, got %v\", config.Volume)\n\t}\n}\n"}, "d2e824162a0bdce4a56aebc045fb0ea8123a4b1b": {"t": 1785759465.5841548, "n": 4933, "h": "feb538bc4a10122f", "c": "package tools\n\nimport (\n\t\"testing\"\n\n\tappconfig \"github.com/difyz9/ytb2bili/internal/config\"\n\t\"go.uber.org/zap\"\n)\n\nfunc TestBuildRuntimeTTSConfigUsesAzureSection(t *testing.T) {\n\tcfg := &appconfig.AppConfig{\n\t\tLLM: appconfig.LLMConfig{\n\t\t\tBaseURL: \"https://api.deepseek.com\",\n\t\t\tAPIKey: \"sk-test\",\n\t\t},\n\t\tTTS: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t},\n\t\tAzureTTS: appconfig.AzureTTSConfig{\n\t\t\tSubscriptionKey: \"azure-subscription\",\n\t\t\tRegion: \"eastasia\",\n\t\t},\n\t\tTencentTTS: appconfig.TencentTTSConfig{\n\t\t\tSecretID: \"tencent-secret-id\",\n\t\t\tSecretKey: \"tencent-secret-key\",\n\t\t\tRegion: \"ap-guangzhou\",\n\t\t},\n\t}\n\n\truntimeCfg := buildRuntimeTTSConfig(cfg)\n\tif runtimeCfg.AzureSubscriptionKey != \"azure-subscription\" {\n\t\tt.Fatalf(\"expected azure subscription key to be loaded, got %q\", runtimeCfg.AzureSubscriptionKey)\n\t}\n\tif runtimeCfg.AzureRegion != \"eastasia\" {\n\t\tt.Fatalf(\"expected azure region to be loaded, got %q\", runtimeCfg.AzureRegion)\n\t}\n\tif runtimeCfg.TencentSecretID != \"tencent-secret-id\" || runtimeCfg.TencentSecretKey != \"tencent-secret-key\" {\n\t\tt.Fatalf(\"expected Tencent credentials to be loaded\")\n\t}\n\tif runtimeCfg.TencentRegion != \"ap-guangzhou\" {\n\t\tt.Fatalf(\"expected Tencent region to be loaded, got %q\", runtimeCfg.TencentRegion)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_LegacyVoiceValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(\"zh-CN-YunxiNeural\")\n\tif !ok {\n\t\tt.Fatal(\"expected legacy voice value to be parsed\")\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice to be parsed, got %q\", config.Voice)\n\t}\n\tif config.Provider != \"\" {\n\t\tt.Fatalf(\"expected provider to remain empty, got %q\", config.Provider)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_JSONValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(`{\"provider\":\"tencent\",\"voice_name\":\"zh-CN-YunxiNeural\",\"language\":\"zh-CN\",\"format\":\"mp3\",\"search\":\"Yunxi\",\"rate\":1.25,\"volume\":88,\"pitch\":3,\"timeout_seconds\":45}`)\n\tif !ok {\n\t\tt.Fatal(\"expected json config to be parsed\")\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider from json, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice from json, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search from json, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format from json, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate from json, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume from json, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch from json, got %v\", config.Pitch)\n\t}\n\tif config.TimeoutSeconds != 45 {\n\t\tt.Fatalf(\"expected timeout from json, got %v\", config.TimeoutSeconds)\n\t}\n}\n\nfunc TestMergeConfig_UsesUserOverridesAndKeepsGlobalCredentials(t *testing.T) {\n\tclient := newTTSClientWithConfig(TTSConfig{\n\t\tBaseURL: \"https://open.ytb2bili.com\",\n\t\tAPIKey: \"sk-test\",\n\t\tProjectID: \"project-default\",\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t\tFormat: \"audio-24khz-96kbitrate-mono-mp3\",\n\t\t\tRate: 1,\n\t\t\tVolume: 100,\n\t\t},\n\t}, nil, zap.NewNop())\n\n\tconfig := client.mergeConfig(client.config, TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"tencent\",\n\t\t\tVoice: \"zh-CN-YunxiNeural\",\n\t\t\tSearch: \"Yunxi\",\n\t\t\tFormat: \"mp3\",\n\t\t\tRate: 1.25,\n\t\t\tVolume: 88,\n\t\t\tPitch: 3,\n\t\t},\n\t})\n\tif config.BaseURL != \"https://open.ytb2bili.com\" {\n\t\tt.Fatalf(\"expected baseURL to stay global, got %q\", config.BaseURL)\n\t}\n\tif config.APIKey != \"sk-test\" {\n\t\tt.Fatalf(\"expected apiKey to stay global, got %q\", config.APIKey)\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider override, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice override, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search override, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format override, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate override, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume override, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch override, got %v\", config.Pitch)\n\t}\n}\n\nfunc TestNormalizeTTSConfig_ClampsVolumeIntoSupportedRange(t *testing.T) {\n\tconfig := normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: 250,\n\t\t},\n\t})\n\tif config.Volume != 100 {\n\t\tt.Fatalf(\"expected volume to be clamped to 100, got %v\", config.Volume)\n\t}\n\n\tconfig = normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: -15,\n\t\t},\n\t})\n\tif config.Volume != 0 {\n\t\tt.Fatalf(\"expected negative volume to be clamped to 0, got %v\", config.Volume)\n\t}\n}\n"}, "17e23548791efcf58f438cc9dfaf85d701fa64e8": {"t": 1785759466.9262671, "n": 4478, "h": "0c992d5683e799db", "c": "package tools\n\nimport (\n\t\"testing\"\n\n\tappconfig \"github.com/difyz9/ytb2bili/internal/config\"\n\t\"go.uber.org/zap\"\n)\n\nfunc TestBuildRuntimeTTSConfigUsesAzureSection(t *testing.T) {\n\tcfg := &appconfig.AppConfig{\n\t\tLLM: appconfig.LLMConfig{\n\t\t\tBaseURL: \"https://api.deepseek.com\",\n\t\t\tAPIKey: \"sk-test\",\n\t\t},\n\t\tTTS: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t},\n\t\tAzureTTS: appconfig.AzureTTSConfig{\n\t\t\tSubscriptionKey: \"azure-subscription\",\n\t\t\tRegion: \"eastasia\",\n\t\t},\n\t}\n\n\truntimeCfg := buildRuntimeTTSConfig(cfg)\n\tif runtimeCfg.AzureSubscriptionKey != \"azure-subscription\" {\n\t\tt.Fatalf(\"expected azure subscription key to be loaded, got %q\", runtimeCfg.AzureSubscriptionKey)\n\t}\n\tif runtimeCfg.AzureRegion != \"eastasia\" {\n\t\tt.Fatalf(\"expected azure region to be loaded, got %q\", runtimeCfg.AzureRegion)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_LegacyVoiceValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(\"zh-CN-YunxiNeural\")\n\tif !ok {\n\t\tt.Fatal(\"expected legacy voice value to be parsed\")\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice to be parsed, got %q\", config.Voice)\n\t}\n\tif config.Provider != \"\" {\n\t\tt.Fatalf(\"expected provider to remain empty, got %q\", config.Provider)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_JSONValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(`{\"provider\":\"tencent\",\"voice_name\":\"zh-CN-YunxiNeural\",\"language\":\"zh-CN\",\"format\":\"mp3\",\"search\":\"Yunxi\",\"rate\":1.25,\"volume\":88,\"pitch\":3,\"timeout_seconds\":45}`)\n\tif !ok {\n\t\tt.Fatal(\"expected json config to be parsed\")\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider from json, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice from json, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search from json, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format from json, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate from json, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume from json, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch from json, got %v\", config.Pitch)\n\t}\n\tif config.TimeoutSeconds != 45 {\n\t\tt.Fatalf(\"expected timeout from json, got %v\", config.TimeoutSeconds)\n\t}\n}\n\nfunc TestMergeConfig_UsesUserOverridesAndKeepsGlobalCredentials(t *testing.T) {\n\tclient := newTTSClientWithConfig(TTSConfig{\n\t\tBaseURL: \"https://open.ytb2bili.com\",\n\t\tAPIKey: \"sk-test\",\n\t\tProjectID: \"project-default\",\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t\tFormat: \"audio-24khz-96kbitrate-mono-mp3\",\n\t\t\tRate: 1,\n\t\t\tVolume: 100,\n\t\t},\n\t}, nil, zap.NewNop())\n\n\tconfig := client.mergeConfig(client.config, TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"tencent\",\n\t\t\tVoice: \"zh-CN-YunxiNeural\",\n\t\t\tSearch: \"Yunxi\",\n\t\t\tFormat: \"mp3\",\n\t\t\tRate: 1.25,\n\t\t\tVolume: 88,\n\t\t\tPitch: 3,\n\t\t},\n\t})\n\tif config.BaseURL != \"https://open.ytb2bili.com\" {\n\t\tt.Fatalf(\"expected baseURL to stay global, got %q\", config.BaseURL)\n\t}\n\tif config.APIKey != \"sk-test\" {\n\t\tt.Fatalf(\"expected apiKey to stay global, got %q\", config.APIKey)\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider override, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice override, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search override, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format override, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate override, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume override, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch override, got %v\", config.Pitch)\n\t}\n}\n\nfunc TestNormalizeTTSConfig_ClampsVolumeIntoSupportedRange(t *testing.T) {\n\tconfig := normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: 250,\n\t\t},\n\t})\n\tif config.Volume != 100 {\n\t\tt.Fatalf(\"expected volume to be clamped to 100, got %v\", config.Volume)\n\t}\n\n\tconfig = normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: -15,\n\t\t},\n\t})\n\tif config.Volume != 0 {\n\t\tt.Fatalf(\"expected negative volume to be clamped to 0, got %v\", config.Volume)\n\t}\n}\n"}, "7347c5df85cf7dd5ab482739d9655f041fc74236": {"t": 1785759468.5210142, "n": 4478, "h": "fa6dc8a30d5526f5", "c": "package tools\n\nimport (\n\t\"testing\"\n\n\tappconfig \"github.com/zolagz/ytb2bili/internal/config\"\n\t\"go.uber.org/zap\"\n)\n\nfunc TestBuildRuntimeTTSConfigUsesAzureSection(t *testing.T) {\n\tcfg := &appconfig.AppConfig{\n\t\tLLM: appconfig.LLMConfig{\n\t\t\tBaseURL: \"https://api.deepseek.com\",\n\t\t\tAPIKey: \"sk-test\",\n\t\t},\n\t\tTTS: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t},\n\t\tAzureTTS: appconfig.AzureTTSConfig{\n\t\t\tSubscriptionKey: \"azure-subscription\",\n\t\t\tRegion: \"eastasia\",\n\t\t},\n\t}\n\n\truntimeCfg := buildRuntimeTTSConfig(cfg)\n\tif runtimeCfg.AzureSubscriptionKey != \"azure-subscription\" {\n\t\tt.Fatalf(\"expected azure subscription key to be loaded, got %q\", runtimeCfg.AzureSubscriptionKey)\n\t}\n\tif runtimeCfg.AzureRegion != \"eastasia\" {\n\t\tt.Fatalf(\"expected azure region to be loaded, got %q\", runtimeCfg.AzureRegion)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_LegacyVoiceValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(\"zh-CN-YunxiNeural\")\n\tif !ok {\n\t\tt.Fatal(\"expected legacy voice value to be parsed\")\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice to be parsed, got %q\", config.Voice)\n\t}\n\tif config.Provider != \"\" {\n\t\tt.Fatalf(\"expected provider to remain empty, got %q\", config.Provider)\n\t}\n}\n\nfunc TestParseStoredUserTTSConfig_JSONValue(t *testing.T) {\n\tconfig, ok := parseStoredUserTTSConfig(`{\"provider\":\"tencent\",\"voice_name\":\"zh-CN-YunxiNeural\",\"language\":\"zh-CN\",\"format\":\"mp3\",\"search\":\"Yunxi\",\"rate\":1.25,\"volume\":88,\"pitch\":3,\"timeout_seconds\":45}`)\n\tif !ok {\n\t\tt.Fatal(\"expected json config to be parsed\")\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider from json, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice from json, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search from json, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format from json, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate from json, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume from json, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch from json, got %v\", config.Pitch)\n\t}\n\tif config.TimeoutSeconds != 45 {\n\t\tt.Fatalf(\"expected timeout from json, got %v\", config.TimeoutSeconds)\n\t}\n}\n\nfunc TestMergeConfig_UsesUserOverridesAndKeepsGlobalCredentials(t *testing.T) {\n\tclient := newTTSClientWithConfig(TTSConfig{\n\t\tBaseURL: \"https://open.ytb2bili.com\",\n\t\tAPIKey: \"sk-test\",\n\t\tProjectID: \"project-default\",\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"auto\",\n\t\t\tVoice: \"zh-CN-XiaoxiaoNeural\",\n\t\t\tLocale: \"zh-CN\",\n\t\t\tFormat: \"audio-24khz-96kbitrate-mono-mp3\",\n\t\t\tRate: 1,\n\t\t\tVolume: 100,\n\t\t},\n\t}, nil, zap.NewNop())\n\n\tconfig := client.mergeConfig(client.config, TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tProvider: \"tencent\",\n\t\t\tVoice: \"zh-CN-YunxiNeural\",\n\t\t\tSearch: \"Yunxi\",\n\t\t\tFormat: \"mp3\",\n\t\t\tRate: 1.25,\n\t\t\tVolume: 88,\n\t\t\tPitch: 3,\n\t\t},\n\t})\n\tif config.BaseURL != \"https://open.ytb2bili.com\" {\n\t\tt.Fatalf(\"expected baseURL to stay global, got %q\", config.BaseURL)\n\t}\n\tif config.APIKey != \"sk-test\" {\n\t\tt.Fatalf(\"expected apiKey to stay global, got %q\", config.APIKey)\n\t}\n\tif config.Provider != \"tencent\" {\n\t\tt.Fatalf(\"expected provider override, got %q\", config.Provider)\n\t}\n\tif config.Voice != \"zh-CN-YunxiNeural\" {\n\t\tt.Fatalf(\"expected voice override, got %q\", config.Voice)\n\t}\n\tif config.Search != \"Yunxi\" {\n\t\tt.Fatalf(\"expected search override, got %q\", config.Search)\n\t}\n\tif config.Format != \"mp3\" {\n\t\tt.Fatalf(\"expected format override, got %q\", config.Format)\n\t}\n\tif config.Rate != 1.25 {\n\t\tt.Fatalf(\"expected rate override, got %v\", config.Rate)\n\t}\n\tif config.Volume != 88 {\n\t\tt.Fatalf(\"expected volume override, got %v\", config.Volume)\n\t}\n\tif config.Pitch != 3 {\n\t\tt.Fatalf(\"expected pitch override, got %v\", config.Pitch)\n\t}\n}\n\nfunc TestNormalizeTTSConfig_ClampsVolumeIntoSupportedRange(t *testing.T) {\n\tconfig := normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: 250,\n\t\t},\n\t})\n\tif config.Volume != 100 {\n\t\tt.Fatalf(\"expected volume to be clamped to 100, got %v\", config.Volume)\n\t}\n\n\tconfig = normalizeTTSConfig(TTSConfig{\n\t\tTTSConfig: appconfig.TTSConfig{\n\t\t\tVolume: -15,\n\t\t},\n\t})\n\tif config.Volume != 0 {\n\t\tt.Fatalf(\"expected negative volume to be clamped to 0, got %v\", config.Volume)\n\t}\n}\n"}}, "config.toml.example": {"7a76c7b491d563e88aa452b5bc774be26e4fbecd": {"t": 1785746804.8284142, "n": 3282, "h": "7d485beea55586af", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n[auth]\njwt_secret = \"change-this-local-jwt-secret\"\naccess_token_ttl = 7200\nrefresh_token_ttl = 604800\n\n# 可以自定义登录账号\n[[auth.users]]\nemail = \"admin@126.com\"\npassword = \"123456\"\n\n\n\n\n# 浏览器插件提交必须启用 HMAC 签名验证。请将下列两个密钥替换成各自\n# 随机生成的 32+ 字符值,并在支持签名的插件中配置相同的 app_id/app_secret。\n[api_auth]\nenabled = true\napp_id = \"ytb2bili_extension\"\napp_secret = \"replace-with-a-random-extension-hmac-secret\"\ncookies_decrypt_key = \"replace-with-a-separate-32-byte-cookie-key\"\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n\n# ==========================================================================\n# 宿主机 Apple Silicon ASR(Docker 通过 host.docker.internal 调用)\n# ==========================================================================\n[asr]\n# local_mlx_whisper 使用 host_asr/ 的 MLX Whisper + WhisperX CPU 服务。\n# bcut 仍可作为 provider 或显式 fallback_provider 使用。\nprovider = \"local_mlx_whisper\"\nfallback_provider = \"\" # 需要 BCut 回退时设置为 \"bcut\"\nbase_url = \"http://host.docker.internal:9000/v1\"\napi_key = \"\"\nmodel = \"mlx-community/whisper-large-v3-turbo\"\n# 已知源语言必须填写,例如 \"en\";留空时仅在任务未指定源语言时自动检测。\nlanguage = \"\"\ntimeout_seconds = 1800\n\n[llm]\nprovider = \"deepseek\" # 服务商: openai, deepseek, ollama, qwen, zhipu, groq, custom\nbase_url = \"https://api.deepseek.com\" # API 端点地址(OpenAI 兼容接口)\napi_key = \"sk-xxxxxxxxxxxx\"\nmodels = [\"deepseek-v4-flash\", \"deepseek-chat\", \"deepseek-reasoner\"] # 前端可选模型列表\ntemperature = 0.7 # 温度参数 (0.0-2.0)\nmax_tokens = 24096 # 每次请求最大 token 数\ntimeout = 300 # 请求超时(秒)\n\n\n\n\n\n# ============================================================================\n# Azure TTS 语音合成配置(用户自行配置)\n# ============================================================================\n[azure_tts]\nsubscription_key = \"\" # Azure Speech Services 订阅密钥\nregion = \"\" # Azure 区域\n\n[tencent_tts]\nsecret_id = \"\" # Tencent Cloud SecretId\nsecret_key = \"\" # Tencent Cloud SecretKey\nregion = \"ap-guangzhou\" # Tencent Cloud region\n"}, "d2e824162a0bdce4a56aebc045fb0ea8123a4b1b": {"t": 1785759463.5179834, "n": 3282, "h": "7d485beea55586af", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n[auth]\njwt_secret = \"change-this-local-jwt-secret\"\naccess_token_ttl = 7200\nrefresh_token_ttl = 604800\n\n# 可以自定义登录账号\n[[auth.users]]\nemail = \"admin@126.com\"\npassword = \"123456\"\n\n\n\n\n# 浏览器插件提交必须启用 HMAC 签名验证。请将下列两个密钥替换成各自\n# 随机生成的 32+ 字符值,并在支持签名的插件中配置相同的 app_id/app_secret。\n[api_auth]\nenabled = true\napp_id = \"ytb2bili_extension\"\napp_secret = \"replace-with-a-random-extension-hmac-secret\"\ncookies_decrypt_key = \"replace-with-a-separate-32-byte-cookie-key\"\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n\n# ==========================================================================\n# 宿主机 Apple Silicon ASR(Docker 通过 host.docker.internal 调用)\n# ==========================================================================\n[asr]\n# local_mlx_whisper 使用 host_asr/ 的 MLX Whisper + WhisperX CPU 服务。\n# bcut 仍可作为 provider 或显式 fallback_provider 使用。\nprovider = \"local_mlx_whisper\"\nfallback_provider = \"\" # 需要 BCut 回退时设置为 \"bcut\"\nbase_url = \"http://host.docker.internal:9000/v1\"\napi_key = \"\"\nmodel = \"mlx-community/whisper-large-v3-turbo\"\n# 已知源语言必须填写,例如 \"en\";留空时仅在任务未指定源语言时自动检测。\nlanguage = \"\"\ntimeout_seconds = 1800\n\n[llm]\nprovider = \"deepseek\" # 服务商: openai, deepseek, ollama, qwen, zhipu, groq, custom\nbase_url = \"https://api.deepseek.com\" # API 端点地址(OpenAI 兼容接口)\napi_key = \"sk-xxxxxxxxxxxx\"\nmodels = [\"deepseek-v4-flash\", \"deepseek-chat\", \"deepseek-reasoner\"] # 前端可选模型列表\ntemperature = 0.7 # 温度参数 (0.0-2.0)\nmax_tokens = 24096 # 每次请求最大 token 数\ntimeout = 300 # 请求超时(秒)\n\n\n\n\n\n# ============================================================================\n# Azure TTS 语音合成配置(用户自行配置)\n# ============================================================================\n[azure_tts]\nsubscription_key = \"\" # Azure Speech Services 订阅密钥\nregion = \"\" # Azure 区域\n\n[tencent_tts]\nsecret_id = \"\" # Tencent Cloud SecretId\nsecret_key = \"\" # Tencent Cloud SecretKey\nregion = \"ap-guangzhou\" # Tencent Cloud region\n"}, "7347c5df85cf7dd5ab482739d9655f041fc74236": {"t": 1785759464.8634408, "n": 2502, "h": "ddfcff0dca417f7a", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n[auth]\njwt_secret = \"change-this-local-jwt-secret\"\naccess_token_ttl = 7200\nrefresh_token_ttl = 604800\n\n# 可以自定义登录账号\n[[auth.users]]\nemail = \"admin@126.com\"\npassword = \"123456\"\n\n\n\n\n## 这里不要改\n[api_auth]\nenabled = false\napp_id = \"ytb2bili_extension\"\napp_secret = \"ytb2bili_secret_2026\"\ncookies_decrypt_key = \"59e7052041ce4bd6aff82f6a0bca9cde\"\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n\n# 水印字体文件路径(可选;用于非会员水印 drawtext fontfile)\nwatermark_font_file = \"/app/fonts/watermark.ttf\"\n\n\n[llm]\nprovider = \"deepseek\" # 服务商: openai, deepseek, ollama, qwen, zhipu, groq, custom\nbase_url = \"https://api.deepseek.com\" # API 端点地址(OpenAI 兼容接口)\napi_key = \"sk-xxxxxxxxxxxx\"\nmodels = [\"deepseek-v4-flash\", \"deepseek-chat\", \"deepseek-reasoner\"] # 前端可选模型列表\ntemperature = 0.7 # 温度参数 (0.0-2.0)\nmax_tokens = 24096 # 每次请求最大 token 数\ntimeout = 300 # 请求超时(秒)\n\n\n\n\n\n# ============================================================================\n# Azure TTS 语音合成配置(用户自行配置)\n# ============================================================================\n[azure_tts]\nsubscription_key = \"\" # Azure Speech Services 订阅密钥\nregion = \"\" # Azure 区域\n"}, "80694b6b248d350b577abf6cd64b9ca4fef62673": {"t": 1785759467.6383412, "n": 4339, "h": "1aed9248b5c5435b", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 5688 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"sqlite\" # 数据库类型: sqlite, mysql, postgresql\npath = \"ytb2bili.db\" # SQLite 数据库文件路径\nauto_migrate = true # 是否自动迁移数据库表结构\ntable_prefix = \"\" # 表名前缀(可选)\n\n# MySQL 配置示例(取消注释并修改以使用 MySQL)\n# type = \"mysql\"\n# host = \"127.0.0.1\"\n# port = 3306\n# user = \"root\"\n# password = \"your_password\"\n# dbname = \"ytb2ibili\"\n# timezone = \"Asia/Shanghai\"\n\n# PostgreSQL 配置示例(取消注释并修改以使用 PostgreSQL)\n# type = \"postgresql\"\n# host = \"127.0.0.1\"\n# port = 5432\n# user = \"postgres\"\n# password = \"your_password\"\n# dbname = \"ytb2bili\"\n# sslmode = \"disable\"\n# timezone = \"UTC\"\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/local/bin/ffmpeg\"\n\n\n# 代理地址(可选,用于加速下载)\n# proxy_url = \"http://127.0.0.1:7890\"\n\n# 微软语音服务配置(可选,用于旧版翻译功能)\n# speech_key = \"your_azure_speech_key\"\n# speech_region = \"eastasia\"\n\n# LLM 翻译配置\nllm_translation_enabled = false # 是否启用 LLM 批量翻译(推荐,替代微软翻译)\nllm_translation_batch_size = 25 # 批量翻译每批句子数\nllm_translation_max_workers = 3 # 并发工作者数量\nllm_translation_context_size = 2 # 上下文窗口大小\nllm_translation_source_lang = \"en\" # 源语言代码\nllm_translation_target_lang = \"zh-Hans\" # 目标语言代码\n\n# TTS 字幕音频合成配置\ntts_enabled = false # 是否启用字幕音频合成\n\n# ============================================================================\n# Agent & LLM 配置\n# ============================================================================\n[agent]\nname = \"ytb2bili_agent\" # Agent 名称\n\n[agent.llm]\nprovider = \"openai\" # LLM 提供商: openai, deepseek, openrouter 等\napi_key = \"your_api_key_here\" # LLM API 密钥(必需)\nmodel = \"gpt-4\" # 使用的模型名称\n# base_url = \"https://api.openai.com/v1\" # 自定义 API 地址(可选)\n\n# OpenRouter 示例\n# provider = \"openrouter\"\n# api_key = \"sk-or-v1-...\"\n# base_url = \"https://openrouter.ai/api/v1\"\n# model = \"anthropic/claude-3-sonnet\"\n\n# DeepSeek 示例\n# provider = \"deepseek\"\n# api_key = \"sk-...\"\n# base_url = \"https://api.deepseek.com/v1\"\n# model = \"deepseek-chat\"\n\n\n\n# Google Gemini 示例(base_url 可省略,程序自动设置 OpenAI 兼容端点)\n# provider = \"gemini\"\n# api_key = \"AIzaSyXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"\n# model = \"gemini-2.0-flash\" # 可选: gemini-2.0-flash, gemini-1.5-pro, gemini-2.0-flash-thinking-exp\n# base_url = \"https://generativelanguage.googleapis.com/v1beta/openai\" # 可省略,程序自动填充\n\n\n\n\n\n\n\n# ============================================================================\n# 自动更新配置\n# ============================================================================\n[updater]\nenabled = true # 是否启用更新检查\nauto_update = false # 是否自动更新(建议设为 false,手动更新更安全)\ncheck_interval = 24 # 检查更新间隔(小时),0 表示禁用\n# update_url = \"https://api.github.com/repos/zolagz/ytb2bili/releases/latest\"\n# current_version = \"0.0.1\"\n\n# ============================================================================\n# TTS 服务配置(可选,用于语音合成)\n# ============================================================================\n[tts]\n# base_url = \"https://tts-api.com\"\n# app_id = \"your_app_id\"\n# app_secret = \"your_app_secret\"\n\n# ============================================================================\n# 腾讯云 COS 存储配置(可选,用于云端存储)\n# ============================================================================\n[tencos]\nenabled = false # 是否启用腾讯云 COS 存储\n# cos_bucket_url = \"https://your-bucket.cos.ap-guangzhou.myqcloud.com\"\n# cos_secret_id = \"your_secret_id\"\n# cos_secret_key = \"your_secret_key\"\n# cos_region = \"ap-guangzhou\"\n# cos_bucket = \"your-bucket-name\"\n# sub_app_id = \"your_app_id\"\n"}, "ddcb1c97778e4eb0bdd8f417a0a7e09590227823": {"t": 1785759469.0139496, "n": 4611, "h": "2298afd49dd38e61", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 5688 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"sqlite\" # 数据库类型: sqlite, mysql, postgresql\npath = \"ytb2bili.db\" # SQLite 数据库文件路径\nauto_migrate = true # 是否自动迁移数据库表结构\ntable_prefix = \"\" # 表名前缀(可选)\n\n# MySQL 配置示例(取消注释并修改以使用 MySQL)\n# type = \"mysql\"\n# host = \"127.0.0.1\"\n# port = 3306\n# user = \"root\"\n# password = \"your_password\"\n# dbname = \"ytb2ibili\"\n# timezone = \"Asia/Shanghai\"\n\n# PostgreSQL 配置示例(取消注释并修改以使用 PostgreSQL)\n# type = \"postgresql\"\n# host = \"127.0.0.1\"\n# port = 5432\n# user = \"postgres\"\n# password = \"your_password\"\n# dbname = \"ytb2bili\"\n# sslmode = \"disable\"\n# timezone = \"UTC\"\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/local/bin/ffmpeg\"\n\n\n# 代理地址(可选,用于加速下载)\n# proxy_url = \"http://127.0.0.1:7890\"\n\n# 微软语音服务配置(可选,用于旧版翻译功能)\n# speech_key = \"your_azure_speech_key\"\n# speech_region = \"eastasia\"\n\n# LLM 翻译配置\nllm_translation_enabled = false # 是否启用 LLM 批量翻译(推荐,替代微软翻译)\nllm_translation_batch_size = 25 # 批量翻译每批句子数\nllm_translation_max_workers = 3 # 并发工作者数量\nllm_translation_context_size = 2 # 上下文窗口大小\nllm_translation_source_lang = \"en\" # 源语言代码\nllm_translation_target_lang = \"zh-Hans\" # 目标语言代码\n\n# TTS 字幕音频合成配置\ntts_enabled = false # 是否启用字幕音频合成\n\n# ============================================================================\n# Agent & LLM 配置\n# ============================================================================\n[agent]\nname = \"ytb2bili_agent\" # Agent 名称\n\n[agent.llm]\nprovider = \"openai\" # LLM 提供商: openai, deepseek, openrouter 等\napi_key = \"your_api_key_here\" # LLM API 密钥(必需)\nmodel = \"gpt-4\" # 使用的模型名称\n# base_url = \"https://api.openai.com/v1\" # 自定义 API 地址(可选)\n\n# OpenRouter 示例\n# provider = \"openrouter\"\n# api_key = \"sk-or-v1-...\"\n# base_url = \"https://openrouter.ai/api/v1\"\n# model = \"anthropic/claude-3-sonnet\"\n\n# DeepSeek 示例\n# provider = \"deepseek\"\n# api_key = \"sk-...\"\n# base_url = \"https://api.deepseek.com/v1\"\n# model = \"deepseek-chat\"\n\n# ============================================================================\n# Firebase 配置(可选,用于用户认证)\n# ============================================================================\n[firebase]\nenabled = false # 是否启用 Firebase 认证\n# credentials_path = \"/path/to/firebase-credentials.json\"\n# project_id = \"your-project-id\"\n\n# ============================================================================\n# TikHub API 配置(可选,用于抖音相关功能)\n# ============================================================================\n[tikhub]\n# api_key = \"your_tikhub_api_key\"\n# base_url = \"https://api.tikhub.io\"\n\n\n\n\n# ============================================================================\n# 自动更新配置\n# ============================================================================\n[updater]\nenabled = true # 是否启用更新检查\nauto_update = false # 是否自动更新(建议设为 false,手动更新更安全)\ncheck_interval = 24 # 检查更新间隔(小时),0 表示禁用\n# update_url = \"https://api.github.com/repos/zolagz/ytb2bili/releases/latest\"\n# current_version = \"0.0.1\"\n\n# ============================================================================\n# TTS 服务配置(可选,用于语音合成)\n# ============================================================================\n[tts]\n# base_url = \"https://tts-api.com\"\n# app_id = \"your_app_id\"\n# app_secret = \"your_app_secret\"\n\n# ============================================================================\n# 腾讯云 COS 存储配置(可选,用于云端存储)\n# ============================================================================\n[tencos]\nenabled = false # 是否启用腾讯云 COS 存储\n# cos_bucket_url = \"https://your-bucket.cos.ap-guangzhou.myqcloud.com\"\n# cos_secret_id = \"your_secret_id\"\n# cos_secret_key = \"your_secret_key\"\n# cos_region = \"ap-guangzhou\"\n# cos_bucket = \"your-bucket-name\"\n# sub_app_id = \"your_app_id\"\n"}, "b63a7f8366f6551a82a04322aecc8ac66ee0904b": {"t": 1785759471.1433947, "n": 2558, "h": "d0e6b17fced6d516", "c": "# Bilibili 视频上传后端 - 配置文件\n\nlisten = \":8096\"\nenvironment = \"development\"\ndebug = true\nfileUpDir = \"./media\"\ndata_path = \"./data\"\nyt_dlp_path = \"\"\n\n[database]\n type = \"mysql\"\n host = \"localhost\"\n port = 3306\n username = \"root\"\n password = \"your_password\"\n database = \"bili_up\"\n ssl_mode = \"\"\n timezone = \"Asia/Shanghai\"\n\n[auth]\n jwt_secret = \"your-jwt-secret-key\"\n jwt_expiration = 24\n session_secret = \"your-session-secret\"\n\n\n[TenCosConfig]\n Enabled = false\n CosBucketURL = \"\"\n CosSecretId = \"\"\n CosSecretKey = \"\"\n CosRegion = \"\"\n CosBucket = \"\"\n SubAppId = \"\"\n CosUrL = \"\"\n\n[DeepSeekTransConfig]\n enabled = true\n api_key = \"sk-deepseek_api_key\"\n models = \"\"\n endpoint = \"https://api.deepseek.com\"\n timeout = 60\n max_tokens = 4000\n\n[GeminiConfig]\n enabled = false # 是否启用Gemini服务\n api_key = \"\" # Google AI API密钥(从 https://aistudio.google.com/app/apikey 获取)\n model = \"gemini-2.5-flash\" # 使用的模型(gemini-2.5-flash 快速, gemini-2.5-pro 强大)\n timeout = 120 # 超时时间(秒)\n max_tokens = 8000 # 最大输出token数\n use_for_metadata = false # 是否使用Gemini生成元数据(优先于DeepSeek)\n analyze_video = true # 是否分析视频文件(true=多模态分析,false=仅文本)\n video_sample_frames = 0 # 视频采样帧数(0=上传完整视频)\n\n[ProxyConfig]\n use_proxy = false\n proxy_host = \"http://127.0.0.1:7890\"\n\n[AnalyticsConfig]\n enabled = false\n server_url = \"http://localhost:8080\"\n api_key = \"\"\n product_id = \"bili-up-api\"\n debug = false\n encryption_key = \"\"\n\n[BilibiliConfig]\n copyright = 2 # 1=自制, 2=转载\n source = \"YouTube\" # 转载来源\n no_reprint = 1 # 0=允许转载, 1=禁止转载\n use_original_title = true # true=使用原视频标题, false=使用AI生成标题\n use_original_desc = false # true=使用原视频描述, false=使用AI生成描述\n custom_title_template = \"\" # 自定义标题模板(可选),支持变量: {original_title}, {ai_title}\n # 示例: \"{original_title}【中文字幕】\" 或 \"【原神MMD】{ai_title}\"\n custom_desc_template = \"\" # 自定义描述模板(可选),支持变量: {original_desc}, {ai_desc}\n \n # 新增配置项\n tid = 122 # 分区ID(122=日常,138=搞笑,详见B站分区列表)\n dynamic = \"发布了新视频!\" # 动态文本\n open_elec = 0 # 是否开启充电面板 0=关闭, 1=开启\n selection_reserve = 0 # 参与活动ID(0表示不参与,暂不被SDK支持)\n up_selection_reply = 0 # 是否展示推荐评论 0=关闭, 1=开启(暂不被SDK支持)\n up_close_reply = 0 # 是否关闭评论 0=开启评论, 1=关闭评论(暂不被SDK支持)\n up_close_reward = 0 # 是否关闭打赏 0=开启, 1=关闭(暂不被SDK支持)\n\n # 自定义描述模板示例:\n # custom_desc_template = \"\"\"\n # 【视频内容】\n # {ai_desc}\n # \n # 【原视频描述】\n # {original_desc}\n # \"\"\"\n"}, "71b8e40a3cfe765bd31876b125c7553cf4c38146": {"t": 1785759472.6025252, "n": 2748, "h": "5509868e4d5937d1", "c": "# Bilibili 视频上传后端 - 配置文件\n\nlisten = \":8096\"\nenvironment = \"development\"\ndebug = true\nfileUpDir = \"./media\"\ndata_path = \"./data\"\nyt_dlp_path = \"\"\n\n[database]\n type = \"mysql\"\n host = \"localhost\"\n port = 3306\n username = \"root\"\n password = \"your_password\"\n database = \"bili_up\"\n ssl_mode = \"\"\n timezone = \"Asia/Shanghai\"\n\n[auth]\n jwt_secret = \"your-jwt-secret-key\"\n jwt_expiration = 24\n session_secret = \"your-session-secret\"\n\n[api_auth]\n app_id = \"ytb2bili_extension\" # 应用ID\n app_secret = \"334567890-3456789045678\" # 应用密钥\n cookies_decrypt_key = \"234567804567893456789456789\" # Cookies 解密密钥\n\n[TenCosConfig]\n Enabled = false\n CosBucketURL = \"\"\n CosSecretId = \"\"\n CosSecretKey = \"\"\n CosRegion = \"\"\n CosBucket = \"\"\n SubAppId = \"\"\n CosUrL = \"\"\n\n[DeepSeekTransConfig]\n enabled = true\n api_key = \"sk-deepseek_api_key\"\n models = \"\"\n endpoint = \"https://api.deepseek.com\"\n timeout = 60\n max_tokens = 4000\n\n[GeminiConfig]\n enabled = false # 是否启用Gemini服务\n api_key = \"\" # Google AI API密钥(从 https://aistudio.google.com/app/apikey 获取)\n model = \"gemini-2.5-flash\" # 使用的模型(gemini-2.5-flash 快速, gemini-2.5-pro 强大)\n timeout = 120 # 超时时间(秒)\n max_tokens = 8000 # 最大输出token数\n use_for_metadata = false # 是否使用Gemini生成元数据(优先于DeepSeek)\n analyze_video = true # 是否分析视频文件(true=多模态分析,false=仅文本)\n video_sample_frames = 0 # 视频采样帧数(0=上传完整视频)\n\n[ProxyConfig]\n use_proxy = false\n proxy_host = \"http://127.0.0.1:7890\"\n\n[AnalyticsConfig]\n enabled = false\n server_url = \"http://localhost:8080\"\n api_key = \"\"\n product_id = \"bili-up-api\"\n debug = false\n encryption_key = \"\"\n\n[BilibiliConfig]\n copyright = 2 # 1=自制, 2=转载\n source = \"YouTube\" # 转载来源\n no_reprint = 1 # 0=允许转载, 1=禁止转载\n use_original_title = true # true=使用原视频标题, false=使用AI生成标题\n use_original_desc = false # true=使用原视频描述, false=使用AI生成描述\n custom_title_template = \"\" # 自定义标题模板(可选),支持变量: {original_title}, {ai_title}\n # 示例: \"{original_title}【中文字幕】\" 或 \"【原神MMD】{ai_title}\"\n custom_desc_template = \"\" # 自定义描述模板(可选),支持变量: {original_desc}, {ai_desc}\n \n # 新增配置项\n tid = 122 # 分区ID(122=日常,138=搞笑,详见B站分区列表)\n dynamic = \"发布了新视频!\" # 动态文本\n open_elec = 0 # 是否开启充电面板 0=关闭, 1=开启\n selection_reserve = 0 # 参与活动ID(0表示不参与,暂不被SDK支持)\n up_selection_reply = 0 # 是否展示推荐评论 0=关闭, 1=开启(暂不被SDK支持)\n up_close_reply = 0 # 是否关闭评论 0=开启评论, 1=关闭评论(暂不被SDK支持)\n up_close_reward = 0 # 是否关闭打赏 0=开启, 1=关闭(暂不被SDK支持)\n\n # 自定义描述模板示例:\n # custom_desc_template = \"\"\"\n # 【视频内容】\n # {ai_desc}\n # \n # 【原视频描述】\n # {original_desc}\n # \"\"\"\n"}, "ca2ca636a07c17d0cd3ca59c99790154f70a8bd0": {"t": 1785759473.815877, "n": 2563, "h": "f0f7bc652424c7ae", "c": "# Bilibili 视频上传后端 - 配置文件\n\nlisten = \":8096\"\nenvironment = \"development\"\ndebug = true\nfileUpDir = \"/Users/apple/opt/file_upload/media\"\nyt_dlp_path = \"\"\n\n[database]\n type = \"mysql\"\n host = \"localhost\"\n port = 3306\n username = \"root\"\n password = \"your_password\"\n database = \"bili_up\"\n ssl_mode = \"\"\n timezone = \"Asia/Shanghai\"\n\n[auth]\n jwt_secret = \"your-jwt-secret-key\"\n jwt_expiration = 24\n session_secret = \"your-session-secret\"\n\n[TenCosConfig]\n Enabled = false\n CosBucketURL = \"\"\n CosSecretId = \"\"\n CosSecretKey = \"\"\n CosRegion = \"\"\n CosBucket = \"\"\n SubAppId = \"\"\n CosUrL = \"\"\n\n[DeepSeekTransConfig]\n enabled = true\n api_key = \"sk-deepseek_api_key\"\n models = \"\"\n endpoint = \"https://api.deepseek.com\"\n timeout = 60\n max_tokens = 4000\n\n[GeminiConfig]\n enabled = false # 是否启用Gemini服务\n api_key = \"\" # Google AI API密钥(从 https://aistudio.google.com/app/apikey 获取)\n model = \"gemini-2.5-flash\" # 使用的模型(gemini-2.5-flash 快速, gemini-2.5-pro 强大)\n timeout = 120 # 超时时间(秒)\n max_tokens = 8000 # 最大输出token数\n use_for_metadata = false # 是否使用Gemini生成元数据(优先于DeepSeek)\n analyze_video = true # 是否分析视频文件(true=多模态分析,false=仅文本)\n video_sample_frames = 0 # 视频采样帧数(0=上传完整视频)\n\n[ProxyConfig]\n use_proxy = false\n proxy_host = \"http://127.0.0.1:7890\"\n\n[AnalyticsConfig]\n enabled = false\n server_url = \"http://localhost:8080\"\n api_key = \"\"\n product_id = \"bili-up-api\"\n debug = false\n encryption_key = \"\"\n\n[BilibiliConfig]\n copyright = 2 # 1=自制, 2=转载\n source = \"YouTube\" # 转载来源\n no_reprint = 1 # 0=允许转载, 1=禁止转载\n use_original_title = true # true=使用原视频标题, false=使用AI生成标题\n use_original_desc = false # true=使用原视频描述, false=使用AI生成描述\n custom_title_template = \"\" # 自定义标题模板(可选),支持变量: {original_title}, {ai_title}\n # 示例: \"{original_title}【中文字幕】\" 或 \"【原神MMD】{ai_title}\"\n custom_desc_template = \"\" # 自定义描述模板(可选),支持变量: {original_desc}, {ai_desc}\n \n # 新增配置项\n tid = 122 # 分区ID(122=日常,138=搞笑,详见B站分区列表)\n dynamic = \"发布了新视频!\" # 动态文本\n open_elec = 0 # 是否开启充电面板 0=关闭, 1=开启\n selection_reserve = 0 # 参与活动ID(0表示不参与,暂不被SDK支持)\n up_selection_reply = 0 # 是否展示推荐评论 0=关闭, 1=开启(暂不被SDK支持)\n up_close_reply = 0 # 是否关闭评论 0=开启评论, 1=关闭评论(暂不被SDK支持)\n up_close_reward = 0 # 是否关闭打赏 0=开启, 1=关闭(暂不被SDK支持)\n\n # 自定义描述模板示例:\n # custom_desc_template = \"\"\"\n # 【视频内容】\n # {ai_desc}\n # \n # 【原视频描述】\n # {original_desc}\n # \"\"\"\n"}, "b6c7986910c09a4c0aca7a9fd19786191d95d5e6": {"t": 1785759475.1727107, "n": 2525, "h": "11c74ac40645ac5d", "c": "# Bilibili 视频上传后端 - 配置文件\n\nlisten = \":8096\"\nenvironment = \"development\"\ndebug = true\nfileUpDir = \"/Users/apple/opt/file_upload/media\"\nyt_dlp_path = \"\"\n\n[database]\n type = \"sqlite\"\n host = \"\"\n port = 0\n username = \"\"\n password = \"\"\n database = \"bili_up.db\"\n ssl_mode = \"\"\n timezone = \"\"\n\n[auth]\n jwt_secret = \"your-jwt-secret-key\"\n jwt_expiration = 24\n session_secret = \"your-session-secret\"\n\n[TenCosConfig]\n Enabled = false\n CosBucketURL = \"\"\n CosSecretId = \"\"\n CosSecretKey = \"\"\n CosRegion = \"\"\n CosBucket = \"\"\n SubAppId = \"\"\n CosUrL = \"\"\n\n[DeepSeekTransConfig]\n enabled = true\n api_key = \"sk-deepseek_api_key\"\n models = \"\"\n endpoint = \"https://api.deepseek.com\"\n timeout = 60\n max_tokens = 4000\n\n[GeminiConfig]\n enabled = false # 是否启用Gemini服务\n api_key = \"\" # Google AI API密钥(从 https://aistudio.google.com/app/apikey 获取)\n model = \"gemini-2.5-flash\" # 使用的模型(gemini-2.5-flash 快速, gemini-2.5-pro 强大)\n timeout = 120 # 超时时间(秒)\n max_tokens = 8000 # 最大输出token数\n use_for_metadata = false # 是否使用Gemini生成元数据(优先于DeepSeek)\n analyze_video = true # 是否分析视频文件(true=多模态分析,false=仅文本)\n video_sample_frames = 0 # 视频采样帧数(0=上传完整视频)\n\n[ProxyConfig]\n use_proxy = false\n proxy_host = \"http://127.0.0.1:7890\"\n\n[AnalyticsConfig]\n enabled = false\n server_url = \"http://localhost:8080\"\n api_key = \"\"\n product_id = \"bili-up-api\"\n debug = false\n encryption_key = \"\"\n\n[BilibiliConfig]\n copyright = 2 # 1=自制, 2=转载\n source = \"YouTube\" # 转载来源\n no_reprint = 1 # 0=允许转载, 1=禁止转载\n use_original_title = true # true=使用原视频标题, false=使用AI生成标题\n use_original_desc = false # true=使用原视频描述, false=使用AI生成描述\n custom_title_template = \"\" # 自定义标题模板(可选),支持变量: {original_title}, {ai_title}\n # 示例: \"{original_title}【中文字幕】\" 或 \"【原神MMD】{ai_title}\"\n custom_desc_template = \"\" # 自定义描述模板(可选),支持变量: {original_desc}, {ai_desc}\n \n # 新增配置项\n tid = 122 # 分区ID(122=日常,138=搞笑,详见B站分区列表)\n dynamic = \"发布了新视频!\" # 动态文本\n open_elec = 0 # 是否开启充电面板 0=关闭, 1=开启\n selection_reserve = 0 # 参与活动ID(0表示不参与,暂不被SDK支持)\n up_selection_reply = 0 # 是否展示推荐评论 0=关闭, 1=开启(暂不被SDK支持)\n up_close_reply = 0 # 是否关闭评论 0=开启评论, 1=关闭评论(暂不被SDK支持)\n up_close_reward = 0 # 是否关闭打赏 0=开启, 1=关闭(暂不被SDK支持)\n\n # 自定义描述模板示例:\n # custom_desc_template = \"\"\"\n # 【视频内容】\n # {ai_desc}\n # \n # 【原视频描述】\n # {original_desc}\n # \"\"\"\n"}, "6eec853377f1fe0e0cad68556b3a545d54d60f98": {"t": 1785759476.4623215, "n": 1428, "h": "ea6d9c49daee2c8a", "c": "# Bilibili 视频上传后端 - 配置文件\n\nlisten = \":8096\"\nenvironment = \"development\"\ndebug = true\nfileUpDir = \"/Users/apple/opt/file_upload/media\"\nyt_dlp_path = \"\"\n\n[database]\n type = \"sqlite\"\n host = \"\"\n port = 0\n username = \"\"\n password = \"\"\n database = \"bili_up.db\"\n ssl_mode = \"\"\n timezone = \"\"\n\n[auth]\n jwt_secret = \"your-jwt-secret-key\"\n jwt_expiration = 24\n session_secret = \"your-session-secret\"\n\n[TenCosConfig]\n Enabled = false\n CosBucketURL = \"\"\n CosSecretId = \"\"\n CosSecretKey = \"\"\n CosRegion = \"\"\n CosBucket = \"\"\n SubAppId = \"\"\n CosUrL = \"\"\n\n[DeepSeekTransConfig]\n enabled = true\n api_key = \"sk-deepseek_api_key\"\n models = \"\"\n endpoint = \"https://api.deepseek.com\"\n timeout = 60\n max_tokens = 4000\n\n[ProxyConfig]\n use_proxy = false\n proxy_host = \"http://127.0.0.1:7890\"\n\n[AnalyticsConfig]\n enabled = false\n server_url = \"http://localhost:8080\"\n api_key = \"\"\n product_id = \"bili-up-api\"\n debug = false\n encryption_key = \"\"\n\n[BilibiliConfig]\n copyright = 2 # 1=自制, 2=转载\n source = \"YouTube\" # 转载来源\n no_reprint = 1 # 0=允许转载, 1=禁止转载\n use_original_title = true # true=使用原视频标题(推荐), false=使用AI生成标题\n use_original_desc = false # true=使用原视频描述, false=使用AI生成描述(推荐)\n custom_desc_template = \"\" # 自定义描述模板(可选),支持变量: {original_desc}, {ai_desc}\n\n # 自定义描述模板示例:\n # custom_desc_template = \"\"\"\n # 【视频内容】\n # {ai_desc}\n # \n # 【原视频描述】\n # {original_desc}\n # \"\"\"\n"}, "d62a2ba3dadd35abf490b520595b5fbcd1656879": {"t": 1785759477.6916194, "n": 956, "h": "35a4562f5c2cdf86", "c": "# Bilibili 视频上传后端 - 配置文件\n\nlisten = \":8096\"\nenvironment = \"development\"\ndebug = true\nfileUpDir = \"/Users/apple/opt/file_upload/media\"\nyt_dlp_path = \"\"\n\n[database]\n type = \"sqlite\"\n host = \"\"\n port = 0\n username = \"\"\n password = \"\"\n database = \"bili_up.db\"\n ssl_mode = \"\"\n timezone = \"\"\n\n[auth]\n jwt_secret = \"your-jwt-secret-key\"\n jwt_expiration = 24\n session_secret = \"your-session-secret\"\n\n[TenCosConfig]\n Enabled = false\n CosBucketURL = \"\"\n CosSecretId = \"\"\n CosSecretKey = \"\"\n CosRegion = \"\"\n CosBucket = \"\"\n SubAppId = \"\"\n CosUrL = \"\"\n\n[DeepSeekTransConfig]\n enabled = true\n api_key = \"sk-deepseek_api_key\"\n models = \"\"\n endpoint = \"https://api.deepseek.com\"\n timeout = 60\n max_tokens = 4000\n\n[ProxyConfig]\n use_proxy = false\n proxy_host = \"http://127.0.0.1:7890\"\n\n[AnalyticsConfig]\n enabled = false\n server_url = \"http://localhost:8080\"\n api_key = \"\"\n product_id = \"bili-up-api\"\n debug = false\n encryption_key = \"\"\n\n\n\n"}, "fda16eb43cbc635cbe8b3373a87408346f8d62ce": {"t": 1785759480.22444, "n": 2486, "h": "d215cdd583ffca7b", "c": "# Bilibili 视频上传后端 - 配置文件\n\n# ======================\n# 基础配置\n# ======================\nlisten = \":8096\" # HTTP 服务监听端口\nenvironment = \"development\" # 运行环境: development, production\ndebug = true # 是否启用调试模式\nFileUpDir = \"/Users/apple/opt/file_upload/media\" # 文件上传目录(绝对路径)\n\n# ======================\n# 数据库配置\n# ======================\n[database]\n type = \"mysql\" # 数据库类型: mysql, postgres\n host = \"localhost\" # 数据库主机\n port = 3306 # 数据库端口\n username = \"root\" # 数据库用户名\n password = \"Ab123456\" # 数据库密码\n database = \"bili_up\" # 数据库名称\n ssl_mode = \"disable\" # SSL 模式\n timezone = \"Asia/Shanghai\" # 时区\n\n# ======================\n# JWT 认证配置\n# ======================\n[auth]\n jwt_secret = \"your-jwt-secret-key\" # JWT 密钥(生产环境请修改)\n jwt_expiration = 24 # JWT 过期时间(小时)\n session_secret = \"your-session-secret\" # Session 密钥(生产环境请修改)\n\n# ======================\n# 腾讯云 COS 存储配置\n# ======================\n[TenCosConfig]\n enabled = true # 是否启用腾讯云 COS 存储\n CosBucketURL = \"https://your-bucket.cos.ap-guangzhou.myqcloud.com\" # COS Bucket URL\n CosSecretId = \"your-secret-id\" # 腾讯云 SecretId\n CosSecretKey = \"your-secret-key\" # 腾讯云 SecretKey\n CosRegion = \"ap-guangzhou\" # COS 地域\n CosBucket = \"your-bucket\" # Bucket 名称\n SubAppId = \"your-appid\" # 子应用ID\n CosUrL = \"https://your-bucket.cos.ap-guangzhou.myqcloud.com\" # COS 访问URL\n\n# ======================\n# 数据分析配置\n# ======================\n[AnalyticsConfig]\n enabled = false # 是否启用数据分析\n server_url = \"http://localhost:8080\" # 分析服务器地址\n api_key = \"your-analytics-api-key\" # API密钥\n product_id = \"bili-up-api\" # 产品ID\n debug = false # 是否启用调试模式\n encryption_key = \"\" # AES加密密钥(可选,16/24/32字节)\n # 示例: \"1234567890123456\" (16字节)\n\n# ======================\n# 说明\n# ======================\n# 以下配置已内置在代码中,无需在此配置文件中设置:\n#\n# 1. BaiduTransConfig - 百度翻译服务\n# 2. DeepSeekTransConfig - DeepSeek AI 服务(可通过API动态配置)\n# 3. app_auth - 应用启动认证\n#\n# 详细说明请参考: docs/CONFIG_GUIDE.md\n"}}, "docker/config.toml.example": {"7a76c7b491d563e88aa452b5bc774be26e4fbecd": {"t": 1785746805.365853, "n": 3132, "h": "b24f038303c4cea9", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n[auth]\njwt_secret = \"change-this-local-jwt-secret\"\naccess_token_ttl = 7200\nrefresh_token_ttl = 604800\n\n# 预定义登录账号\n# 请自定义的账号/密码\n[[auth.users]]\nemail = \"admin@126.com\"\npassword = \"admin123\"\n\n\n# 浏览器插件提交必须启用 HMAC 签名验证。请将下列两个密钥替换成各自\n# 随机生成的 32+ 字符值,并在支持签名的插件中配置相同的 app_id/app_secret。\n[api_auth]\nenabled = true\napp_id = \"ytb2bili_extension\"\napp_secret = \"replace-with-a-random-extension-hmac-secret\"\ncookies_decrypt_key = \"replace-with-a-separate-32-byte-cookie-key\"\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n\n# ==========================================================================\n# 宿主机 Apple Silicon ASR(Docker 通过 host.docker.internal 调用)\n# ==========================================================================\n[asr]\nprovider = \"local_mlx_whisper\"\nfallback_provider = \"\" # 需要 BCut 回退时设置为 \"bcut\"\nbase_url = \"http://host.docker.internal:9000/v1\"\napi_key = \"\"\nmodel = \"mlx-community/whisper-large-v3-turbo\"\nlanguage = \"\"\ntimeout_seconds = 1800\n\n[llm]\nprovider = \"deepseek\" # 服务商: openai, deepseek, ollama, qwen, zhipu, groq, custom\nbase_url = \"https://api.deepseek.com\" # API 端点地址(OpenAI 兼容接口)\napi_key = \"sk-xxxx\"\nmodels = [\"deepseek-v4-flash\", \"deepseek-chat\", \"deepseek-reasoner\"] # 前端可选模型列表\ntemperature = 0.7 # 温度参数 (0.0-2.0)\nmax_tokens = 24096 # 每次请求最大 token 数\ntimeout = 300 # 请求超时(秒)\n\n\n\n\n\n# ============================================================================\n# Azure TTS 语音合成配置(用户自行配置)\n# ============================================================================\n[azure_tts]\nsubscription_key = \"\" # Azure Speech Services 订阅密钥\nregion = \"\" # Azure 区域\n\n[tencent_tts]\nsecret_id = \"\" # Tencent Cloud SecretId\nsecret_key = \"\" # Tencent Cloud SecretKey\nregion = \"ap-guangzhou\" # Tencent Cloud region\n"}, "d2e824162a0bdce4a56aebc045fb0ea8123a4b1b": {"t": 1785759466.4097705, "n": 3132, "h": "b24f038303c4cea9", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n[auth]\njwt_secret = \"change-this-local-jwt-secret\"\naccess_token_ttl = 7200\nrefresh_token_ttl = 604800\n\n# 预定义登录账号\n# 请自定义的账号/密码\n[[auth.users]]\nemail = \"admin@126.com\"\npassword = \"admin123\"\n\n\n# 浏览器插件提交必须启用 HMAC 签名验证。请将下列两个密钥替换成各自\n# 随机生成的 32+ 字符值,并在支持签名的插件中配置相同的 app_id/app_secret。\n[api_auth]\nenabled = true\napp_id = \"ytb2bili_extension\"\napp_secret = \"replace-with-a-random-extension-hmac-secret\"\ncookies_decrypt_key = \"replace-with-a-separate-32-byte-cookie-key\"\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n\n# ==========================================================================\n# 宿主机 Apple Silicon ASR(Docker 通过 host.docker.internal 调用)\n# ==========================================================================\n[asr]\nprovider = \"local_mlx_whisper\"\nfallback_provider = \"\" # 需要 BCut 回退时设置为 \"bcut\"\nbase_url = \"http://host.docker.internal:9000/v1\"\napi_key = \"\"\nmodel = \"mlx-community/whisper-large-v3-turbo\"\nlanguage = \"\"\ntimeout_seconds = 1800\n\n[llm]\nprovider = \"deepseek\" # 服务商: openai, deepseek, ollama, qwen, zhipu, groq, custom\nbase_url = \"https://api.deepseek.com\" # API 端点地址(OpenAI 兼容接口)\napi_key = \"sk-xxxx\"\nmodels = [\"deepseek-v4-flash\", \"deepseek-chat\", \"deepseek-reasoner\"] # 前端可选模型列表\ntemperature = 0.7 # 温度参数 (0.0-2.0)\nmax_tokens = 24096 # 每次请求最大 token 数\ntimeout = 300 # 请求超时(秒)\n\n\n\n\n\n# ============================================================================\n# Azure TTS 语音合成配置(用户自行配置)\n# ============================================================================\n[azure_tts]\nsubscription_key = \"\" # Azure Speech Services 订阅密钥\nregion = \"\" # Azure 区域\n\n[tencent_tts]\nsecret_id = \"\" # Tencent Cloud SecretId\nsecret_key = \"\" # Tencent Cloud SecretKey\nregion = \"ap-guangzhou\" # Tencent Cloud region\n"}, "7347c5df85cf7dd5ab482739d9655f041fc74236": {"t": 1785759467.9859817, "n": 2502, "h": "bcf4c0b2594c29cf", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n[auth]\njwt_secret = \"change-this-local-jwt-secret\"\naccess_token_ttl = 7200\nrefresh_token_ttl = 604800\n\n# 预定义登录账号\n# 请自定义的账号/密码\n[[auth.users]]\nemail = \"admin@126.com\"\npassword = \"admin123\"\n\n\n# 不要修改\n[api_auth]\nenabled = false\napp_id = \"ytb2bili_extension\"\napp_secret = \"ytb2bili_secret_2026\"\ncookies_decrypt_key = \"59e7052041ce4bd6aff82f6a0bca9cde\"\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n\n# 水印字体文件路径(可选;用于非会员水印 drawtext fontfile)\nwatermark_font_file = \"/app/fonts/watermark.ttf\"\n\n\n[llm]\nprovider = \"deepseek\" # 服务商: openai, deepseek, ollama, qwen, zhipu, groq, custom\nbase_url = \"https://api.deepseek.com\" # API 端点地址(OpenAI 兼容接口)\napi_key = \"sk-xxxx\"\nmodels = [\"deepseek-v4-flash\", \"deepseek-chat\", \"deepseek-reasoner\"] # 前端可选模型列表\ntemperature = 0.7 # 温度参数 (0.0-2.0)\nmax_tokens = 24096 # 每次请求最大 token 数\ntimeout = 300 # 请求超时(秒)\n\n\n\n\n\n# ============================================================================\n# Azure TTS 语音合成配置(用户自行配置)\n# ============================================================================\n[azure_tts]\nsubscription_key = \"\" # Azure Speech Services 订阅密钥\nregion = \"\" # Azure 区域\n"}, "604caa3e89ce9b417a5370ecbe94e18ee3e931f0": {"t": 1785759470.3413825, "n": 3028, "h": "34bd5e8a31041c5c", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n# Cookies 文件路径(可选,用于下载受限视频)\n# cookies_file = \"/path/to/cookies.txt\"\n\n# 代理地址(可选,用于加速下载)\n# proxy_url = \"http://127.0.0.1:7890\"\n\n# 微软语音服务配置(可选,用于旧版翻译功能)\n# speech_key = \"your_azure_speech_key\"\n# speech_region = \"eastasia\"\n\n# LLM 翻译配置\nllm_translation_enabled = true # 是否启用 LLM 批量翻译(推荐,替代微软翻译)\nllm_translation_batch_size = 25 # 批量翻译每批句子数\nllm_translation_max_workers = 3 # 并发工作者数量\nllm_translation_context_size = 2 # 上下文窗口大小\nllm_translation_source_lang = \"en\" # 源语言代码\nllm_translation_target_lang = \"zh-Hans\" # 目标语言代码\n\n# TTS 字幕音频合成配置\ntts_enabled = false # 是否启用字幕音频合成\n\n# ============================================================================\n# Agent & LLM 配置\n# ============================================================================\n[agent]\nname = \"agent\" # Agent 名称\n\n\n# ============================================================================\n# 自动更新配置\n# ============================================================================\n[updater]\nenabled = true # 是否启用更新检查\nauto_update = false # 是否自动更新(建议设为 false,手动更新更安全)\ncheck_interval = 24 # 检查更新间隔(小时),0 表示禁用\n# update_url = \"https://api.github.com/repos/zolagz/ytb2bili/releases/latest\"\n# current_version = \"0.0.1\"\n\n\n\n# ============================================================================\n# 腾讯云 COS 存储配置(可选,用于云端存储)\n# ============================================================================\n[tencos]\nenabled = false # 是否启用腾讯云 COS 存储\n# cos_bucket_url = \"https://your-bucket.cos.ap-guangzhou.myqcloud.com\"\n# cos_secret_id = \"your_secret_id\"\n# cos_secret_key = \"your_secret_key\"\n# cos_region = \"ap-guangzhou\"\n# cos_bucket = \"your-bucket-name\"\n# sub_app_id = \"your_app_id\"\n\n"}, "80694b6b248d350b577abf6cd64b9ca4fef62673": {"t": 1785759472.2285154, "n": 3845, "h": "6ebf65288401551c", "c": "# ytb2bili 配置文件示例(TOML格式)\n# 复制此文件为 config.toml 并根据实际情况修改\n# 注意:环境变量会覆盖此文件中的配置\n\n# ============================================================================\n# 应用基础配置\n# ============================================================================\n\n[server]\nhost = \"0.0.0.0\" # 服务监听地址,0.0.0.0 表示监听所有网卡\nport = 8096 # 服务端口\nstatic_dir = \"./downloads\" # 静态文件目录(视频、字幕等)\nstatic_path = \"/static\" # 静态文件访问路径前缀\n\n\n# ============================================================================\n# 数据库配置\n# ============================================================================\n[database]\ntype = \"mysql\"\nhost = \"mysql\" # Docker Compose 服务名\nport = 3306\nuser = \"ytb2bili\" # 与 docker-compose.yml 一致\npassword = \"ytb2bili@123\"\ndbname = \"bili_up\" # 数据库名(注意是 dbname 不是 database)\nsslmode = \"\" # MySQL 不使用(仅 PostgreSQL 需要)\ntimezone = \"Asia/Shanghai\" # 时区配置\nauto_migrate = true\ntable_prefix = \"\"\n\n\n\n# ============================================================================\n# 视频处理工作流配置\n# ============================================================================\n[workflow]\ndownload_dir = \"./downloads\" # 视频下载目录(必需,应与 server.static_dir 保持一致)\n\n# yt-dlp 可执行文件路径(可选,默认从 PATH 查找)\nytdlp_path = \"/usr/local/bin/yt-dlp\"\n\n# ffmpeg 可执行文件路径(可选,默认从 PATH 查找)\nffmpeg_path = \"/usr/bin/ffmpeg\"\n# Cookies 文件路径(可选,用于下载受限视频)\n# cookies_file = \"/path/to/cookies.txt\"\n\n# 代理地址(可选,用于加速下载)\n# proxy_url = \"http://127.0.0.1:7890\"\n\n# 微软语音服务配置(可选,用于旧版翻译功能)\n# speech_key = \"your_azure_speech_key\"\n# speech_region = \"eastasia\"\n\n# LLM 翻译配置\nllm_translation_enabled = true # 是否启用 LLM 批量翻译(推荐,替代微软翻译)\nllm_translation_batch_size = 25 # 批量翻译每批句子数\nllm_translation_max_workers = 3 # 并发工作者数量\nllm_translation_context_size = 2 # 上下文窗口大小\nllm_translation_source_lang = \"en\" # 源语言代码\nllm_translation_target_lang = \"zh-Hans\" # 目标语言代码\n\n# TTS 字幕音频合成配置\ntts_enabled = false # 是否启用字幕音频合成\n\n# ============================================================================\n# Agent & LLM 配置\n# ============================================================================\n[agent]\nname = \"ytb2bili_agent\" # Agent 名称\n\n[agent.llm]\n# provider = \"openai\" # LLM 提供商: openai, deepseek, openrouter 等\n# api_key = \"sk-proj--\" # LLM API 密钥(必需)\n# model = \"gpt-4\" # 使用的模型名称\n# base_url = \"https://api.openai.com/v1\" # 自定义 API 地址(可选)\n\n# OpenRouter 示例\n# provider = \"openrouter\"\n# api_key = \"sk-or-v1-...\"\n# base_url = \"https://openrouter.ai/api/v1\"\n# model = \"anthropic/claude-3-sonnet\"\n\n# DeepSeek 示例\nprovider = \"deepseek\"\napi_key = \"sk\"\nbase_url = \"https://api.deepseek.com/v1\"\nmodel = \"deepseek-chat\"\n\n# ============================================================================\n# 自动更新配置\n# ============================================================================\n[updater]\nenabled = true # 是否启用更新检查\nauto_update = false # 是否自动更新(建议设为 false,手动更新更安全)\ncheck_interval = 24 # 检查更新间隔(小时),0 表示禁用\n# update_url = \"https://api.github.com/repos/zolagz/ytb2bili/releases/latest\"\n# current_version = \"0.0.1\"\n\n# ============================================================================\n# TTS 服务配置(可选,用于语音合成)\n# ============================================================================\n[tts]\n# base_url = \"https://tts-api.com\"\n# app_id = \"your_app_id\"\n# app_secret = \"your_app_secret\"\n\n# ============================================================================\n# 腾讯云 COS 存储配置(可选,用于云端存储)\n# ============================================================================\n[tencos]\nenabled = false # 是否启用腾讯云 COS 存储\n# cos_bucket_url = \"https://your-bucket.cos.ap-guangzhou.myqcloud.com\"\n# cos_secret_id = \"your_secret_id\"\n# cos_secret_key = \"your_secret_key\"\n# cos_region = \"ap-guangzhou\"\n# cos_bucket = \"your-bucket-name\"\n# sub_app_id = \"your_app_id\"\n\n"}}}}