From 31b6b9824ec0681ae6095cd5ea196c6d85e337db Mon Sep 17 00:00:00 2001
From: Symb0x76 <9667434@qq.com>
Date: Fri, 10 Oct 2025 20:53:54 +0800
Subject: [PATCH] fix(build): universal compile for CGO
---
.vscode/settings.json | 3 +-
Makefile | 6 +-
internal/chatlog/conf/tui.go | 1 -
internal/chatlog/ctx/context.go | 5 +-
internal/chatlog/http/route.go | 535 +---------------------
internal/chatlog/http/service.go | 46 --
internal/chatlog/http/static/index.htm | 291 ------------
internal/speech/whispercpp/transcriber.go | 6 -
third_party/whisper/lib/libggml.a | Bin 0 -> 69486 bytes
9 files changed, 11 insertions(+), 882 deletions(-)
create mode 100644 third_party/whisper/lib/libggml.a
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 04e5c00..2781998 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -52,7 +52,8 @@
"variant": "cpp"
},
"go.toolsEnvVars": {
+ "CGO_ENABLED": "1",
"CGO_CFLAGS": "-I${workspaceFolder}/third_party/whisper/include",
- "CGO_LDFLAGS": "-L${workspaceFolder}/third_party/whisper/lib -lwhisper -lggml -lstdc++ -lm"
+ "CGO_LDFLAGS": "-L${workspaceFolder}/third_party/whisper/lib"
}
}
diff --git a/Makefile b/Makefile
index 485b4fa..d59d933 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,8 @@ ifeq ($(VERSION),)
VERSION := $(shell git describe --tags --always --dirty="-dev")
endif
LDFLAGS := -ldflags '-X "github.com/sjzar/chatlog/pkg/version.Version=$(VERSION)" -w -s'
+TAG := --tags "fts5"
+CGO_FLAG := CGO_ENABLED=1 CGO_CFLAGS="-I./third_party/whisper/include" CGO_LDFLAGS="-L./third_party/whisper/lib"
PLATFORMS := \
darwin/amd64 \
@@ -52,7 +54,7 @@ test:
build:
@echo "Building for current platform..."
@$(MKDIR_BIN)
- @CGO_ENABLED=1 $(GO) build --tags "fts5" -trimpath $(LDFLAGS) -o bin/$(BINARY_NAME)$(BINARY_SUFFIX) main.go
+ @$(CGO_FLAG) $(GO) build -trimpath $(LDFLAGS) $(TAG) -o bin/$(BINARY_NAME)$(BINARY_SUFFIX) main.go
@echo "Done!"
crossbuild: clean
@@ -67,7 +69,7 @@ crossbuild: clean
[ "$$os" = "windows" ] && output_name=$$output_name.exe; \
echo "Building for $$os/$$arch..."; \
echo "Building for $$output_name..."; \
- @GOOS=$$os GOARCH=$$arch CGO_ENABLED=1 GOARM=$$float $(GO) build --tags "fts5" -trimpath $(LDFLAGS) -o $$output_name main.go ; \
+ @GOOS=$$os GOARCH=$$arch GOARM=$$float $(CGO_FLAG) $(GO) build -trimpath $(LDFLAGS) $(TAG) -o $$output_name main.go ; \
if [ "$(ENABLE_UPX)" = "1" ] && echo "$(UPX_PLATFORMS)" | grep -q "$$os/$$arch"; then \
echo "Compressing binary $$output_name..." && upx --best $$output_name; \
fi; \
diff --git a/internal/chatlog/conf/tui.go b/internal/chatlog/conf/tui.go
index 993d5ea..2d54fb4 100644
--- a/internal/chatlog/conf/tui.go
+++ b/internal/chatlog/conf/tui.go
@@ -5,7 +5,6 @@ type TUIConfig struct {
LastAccount string `mapstructure:"last_account" json:"last_account"`
History []ProcessConfig `mapstructure:"history" json:"history"`
Webhook *Webhook `mapstructure:"webhook" json:"webhook"`
- Speech *SpeechConfig `mapstructure:"speech" json:"speech"`
}
var TUIDefaults = map[string]any{}
diff --git a/internal/chatlog/ctx/context.go b/internal/chatlog/ctx/context.go
index 5183a74..2453a8d 100644
--- a/internal/chatlog/ctx/context.go
+++ b/internal/chatlog/ctx/context.go
@@ -186,10 +186,7 @@ func (c *Context) GetWebhook() *conf.Webhook {
}
func (c *Context) GetSpeech() *conf.SpeechConfig {
- if c == nil || c.conf == nil {
- return nil
- }
- return c.conf.Speech
+ return nil
}
func (c *Context) SetHTTPEnabled(enabled bool) {
diff --git a/internal/chatlog/http/route.go b/internal/chatlog/http/route.go
index 1d7bf92..4d8a78c 100644
--- a/internal/chatlog/http/route.go
+++ b/internal/chatlog/http/route.go
@@ -30,459 +30,9 @@ var EFS embed.FS
// 统一的 HTML 预览组件片段
var previewHTMLSnippet = `
-
-
-`
+
+
+`
func (s *Service) initRouter() {
s.initBaseRouter()
@@ -527,69 +77,9 @@ func (s *Service) initAPIRouter() {
api.GET("/diary", s.handleDiary)
api.GET("/dashboard", s.handleDashboard)
api.GET("/search", s.handleSearch)
- api.POST("/voice/transcribe", s.handleVoiceTranscribe)
}
}
-func (s *Service) handleVoiceTranscribe(c *gin.Context) {
- if s.speech == nil {
- c.JSON(http.StatusNotImplemented, gin.H{"error": "speech-to-text not enabled"})
- return
- }
-
- var req struct {
- Key string `json:"key"`
- }
- if err := c.ShouldBindJSON(&req); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request payload", "detail": err.Error()})
- return
- }
-
- key := strings.TrimSpace(req.Key)
- if key == "" {
- c.JSON(http.StatusBadRequest, gin.H{"error": "voice key is required"})
- return
- }
-
- media, err := s.db.GetMedia("voice", key)
- if err != nil {
- errors.Err(c, err)
- return
- }
- if media == nil || len(media.Data) == 0 {
- c.JSON(http.StatusNotFound, gin.H{"error": "voice media not found"})
- return
- }
-
- result, err := s.speech.TranscribeSilk(c.Request.Context(), media.Data, s.speechOpts)
- if err != nil {
- c.JSON(http.StatusInternalServerError, gin.H{"error": "transcription failed", "detail": err.Error()})
- return
- }
-
- segments := make([]gin.H, 0, len(result.Segments))
- for _, seg := range result.Segments {
- segments = append(segments, gin.H{
- "id": seg.ID,
- "start": seg.Start.Seconds(),
- "end": seg.End.Seconds(),
- "text": seg.Text,
- })
- }
-
- response := gin.H{
- "text": result.Text,
- "language": result.Language,
- "duration": result.Duration.Seconds(),
- "segments": segments,
- }
- if s.speechCfg != nil {
- response["model"] = strings.TrimSpace(s.speechCfg.Model)
- }
-
- c.JSON(http.StatusOK, response)
-}
-
func (s *Service) initMCPRouter() {
s.router.Any("/mcp", func(c *gin.Context) { s.mcpStreamableServer.ServeHTTP(c.Writer, c.Request) })
s.router.Any("/sse", func(c *gin.Context) { s.mcpSSEServer.ServeHTTP(c.Writer, c.Request) })
@@ -1050,7 +540,7 @@ func (s *Service) handleDashboard(c *gin.Context) {
Messages: v.MsgCount,
Avatar: s.composeAvatarURL(k),
})
- added++;
+ added++
}
}
}
@@ -2192,23 +1682,6 @@ func messageHTMLPlaceholder(m *model.Message) string {
anchorText = "[" + escapedFull + "]"
} else if left == "文件" && rest != "" { // 文件保留文件名
anchorText = "[文件]" + template.HTMLEscapeString(rest)
- } else if strings.HasPrefix(left, "语音") {
- anchorText = "[" + template.HTMLEscapeString(left) + "]"
- voiceURL := template.HTMLEscapeString(url)
- voiceKey := ""
- if idx := strings.Index(url, "/voice/"); idx >= 0 {
- keyPart := url[idx+len("/voice/"):]
- if cut := strings.IndexAny(keyPart, "?#"); cut >= 0 {
- keyPart = keyPart[:cut]
- }
- voiceKey = keyPart
- }
- escapedKey := template.HTMLEscapeString(voiceKey)
- anchor := `` + anchorText + ``
- button := ``
- transcript := ``
- container := `` + anchor + ` ` + button + ` ` + transcript + ``
- return container
} else {
anchorText = "[" + template.HTMLEscapeString(left) + "]"
}
diff --git a/internal/chatlog/http/service.go b/internal/chatlog/http/service.go
index c30e761..5b1354b 100644
--- a/internal/chatlog/http/service.go
+++ b/internal/chatlog/http/service.go
@@ -3,18 +3,14 @@ package http
import (
"context"
"net/http"
- "strings"
"time"
"github.com/gin-gonic/gin"
"github.com/mark3labs/mcp-go/server"
"github.com/rs/zerolog/log"
- "github.com/sjzar/chatlog/internal/chatlog/conf"
"github.com/sjzar/chatlog/internal/chatlog/database"
"github.com/sjzar/chatlog/internal/errors"
- "github.com/sjzar/chatlog/internal/speech"
- "github.com/sjzar/chatlog/internal/speech/whispercpp"
)
type Service struct {
@@ -27,17 +23,11 @@ type Service struct {
mcpServer *server.MCPServer
mcpSSEServer *server.SSEServer
mcpStreamableServer *server.StreamableHTTPServer
-
- speechCfg *conf.SpeechConfig
- speechOpts speech.Options
- speech speech.Transcriber
- speechErr error
}
type Config interface {
GetHTTPAddr() string
GetDataDir() string
- GetSpeech() *conf.SpeechConfig
}
func NewService(conf Config, db *database.Service) *Service {
@@ -65,7 +55,6 @@ func NewService(conf Config, db *database.Service) *Service {
s.initMCPServer()
s.initRouter()
- s.initSpeech()
return s
}
@@ -115,44 +104,9 @@ func (s *Service) Stop() error {
}
log.Info().Msg("HTTP server stopped")
- s.shutdownSpeech()
return nil
}
func (s *Service) GetRouter() *gin.Engine {
return s.router
}
-
-func (s *Service) initSpeech() {
- cfg := s.conf.GetSpeech()
- if cfg == nil || !cfg.Enabled {
- return
- }
-
- modelPath := strings.TrimSpace(cfg.Model)
- if modelPath == "" {
- log.Warn().Msg("speech config enabled but model path is empty; disabling speech backend")
- return
- }
-
- opts := cfg.ToOptions()
- transcriber, err := whispercpp.New(whispercpp.Config{ModelPath: modelPath, DefaultOptions: opts})
- if err != nil {
- log.Err(err).Str("model", modelPath).Msg("failed to initialize whisper backend; speech disabled")
- s.speechErr = err
- return
- }
-
- s.speechCfg = cfg
- s.speechOpts = opts
- s.speech = transcriber
- log.Info().Str("model", modelPath).Msg("speech-to-text backend initialized")
-}
-
-func (s *Service) shutdownSpeech() {
- if s.speech != nil {
- s.speech.Close()
- s.speech = nil
- log.Info().Msg("speech-to-text backend stopped")
- }
-}
diff --git a/internal/chatlog/http/static/index.htm b/internal/chatlog/http/static/index.htm
index 3f18748..f2f6df1 100644
--- a/internal/chatlog/http/static/index.htm
+++ b/internal/chatlog/http/static/index.htm
@@ -365,93 +365,6 @@
color: var(--error-color);
font-weight: bold;
}
-
- .voice-message {
- display: inline-flex;
- flex-direction: column;
- gap: 6px;
- align-items: flex-start;
- background: rgba(46, 189, 240, 0.08);
- padding: 6px 8px;
- border-radius: 8px;
- margin: 4px 0;
- }
-
- .voice-message .voice-stt-btn {
- background-color: #2d333b;
- border: 1px solid #4d6277;
- color: #d7e2f2;
- font-size: 12px;
- padding: 4px 10px;
- border-radius: 4px;
- cursor: pointer;
- transition: background 0.2s ease, opacity 0.2s ease;
- }
-
- .voice-message .voice-stt-btn:hover {
- background-color: #3a4a5b;
- }
-
- .voice-message .voice-stt-btn[disabled] {
- opacity: 0.65;
- cursor: wait;
- }
-
- .voice-message .voice-transcript {
- font-size: 13px;
- color: #2c3e50;
- background: rgba(255, 255, 255, 0.7);
- padding: 6px 8px;
- border-radius: 6px;
- line-height: 1.6;
- white-space: pre-wrap;
- word-break: break-word;
- max-width: 600px;
- }
-
- .voice-message .voice-transcript[data-state="idle"] {
- display: none;
- }
-
- .voice-message .voice-text {
- white-space: pre-wrap;
- word-break: break-word;
- }
-
- .voice-message .voice-transcript .voice-segment {
- padding: 4px 0;
- border-left: 2px solid rgba(52, 152, 219, 0.45);
- margin-top: 4px;
- padding-left: 8px;
- }
-
- .voice-message .voice-transcript .voice-segment-time {
- font-size: 12px;
- color: #6c7a89;
- }
-
- .voice-message .voice-segments {
- display: flex;
- flex-direction: column;
- gap: 6px;
- margin-top: 8px;
- }
-
- .voice-message .voice-meta,
- .voice-message .voice-transcript .voice-meta {
- margin-top: 6px;
- font-size: 12px;
- color: #6c7a89;
- }
-
- .voice-message .voice-transcript .voice-segment span {
- display: block;
- }
-
- .voice-message .voice-text.voice-empty {
- color: #95a5a6;
- font-style: italic;
- }
@@ -1261,7 +1174,6 @@
resultContainer.innerHTML = `${highlighted}`;
}
}
- prepareVoiceMessages(resultContainer);
} catch (error) {
resultContainer.innerHTML = "";
errorMessage.textContent = `查询出错: ${error.message}`;
@@ -1376,209 +1288,6 @@
});
}
- const voiceFallbackCache = new Map();
-
- function prepareVoiceMessages(root) {
- if (!root) return;
- if (
- window.ChatlogSpeech &&
- typeof window.ChatlogSpeech.refreshVoiceMessages ===
- "function"
- ) {
- window.ChatlogSpeech.refreshVoiceMessages();
- return;
- }
- fallbackEnsureVoiceState(root);
- }
-
- function fallbackEnsureVoiceState(root) {
- root.querySelectorAll(".voice-message").forEach((container) => {
- const transcript =
- container.querySelector(".voice-transcript");
- if (transcript && !transcript.dataset.state) {
- transcript.dataset.state = "idle";
- }
- const btn = container.querySelector(".voice-stt-btn");
- if (btn && !btn.dataset.labelIdle) {
- btn.dataset.labelIdle = btn.textContent.trim();
- }
- });
- }
-
- function voiceKeyFromButton(btn) {
- const container = btn.closest(".voice-message");
- if (!container) return "";
- const link = container.querySelector(
- "a.voice-original, a[href]"
- );
- if (!link) return "";
- const href = link.getAttribute("href") || "";
- try {
- const url = new URL(href, window.location.href);
- return (
- url.searchParams.get("msgid") ||
- url.searchParams.get("id") ||
- url.pathname
- );
- } catch (_err) {
- return href;
- }
- }
-
- async function fallbackVoiceRequest(btn) {
- const container = btn.closest(".voice-message");
- const transcript =
- container?.querySelector(".voice-transcript");
- const key = voiceKeyFromButton(btn);
- if (!container || !transcript || !key) return;
-
- if (!transcript.dataset.state) {
- transcript.dataset.state = "idle";
- }
-
- const cached = voiceFallbackCache.get(key);
- if (cached) {
- transcript.innerHTML = renderTranscript(cached);
- transcript.dataset.state = "ready";
- btn.disabled = false;
- btn.dataset.state = "done";
- btn.textContent = "查看文字";
- return;
- }
-
- const originalText =
- btn.dataset.labelIdle || btn.textContent || "语音转文字";
- btn.dataset.labelIdle = originalText;
- btn.disabled = true;
- btn.dataset.state = "loading";
- btn.textContent = "转文字中…";
-
- transcript.dataset.state = "loading";
- transcript.textContent = "语音识别进行中…";
-
- try {
- const response = await fetch("/api/v1/voice/transcribe", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify({ key }),
- });
- if (!response.ok) {
- throw new Error(`HTTP ${response.status}`);
- }
- const payload = await response.json();
- voiceFallbackCache.set(key, payload);
- transcript.innerHTML = renderTranscript(payload);
- transcript.dataset.state = "ready";
- btn.disabled = false;
- btn.textContent = "已转文字";
- btn.dataset.state = "done";
- } catch (err) {
- console.error("语音识别失败:", err);
- transcript.dataset.state = "error";
- transcript.textContent = `转文字失败: ${err.message}`;
- btn.textContent = "重试转文字";
- btn.dataset.state = "error";
- } finally {
- btn.disabled = false;
- }
- }
-
- function renderTranscript(data) {
- const pieces = [];
- const rawText =
- data && typeof data.text === "string"
- ? data.text.trim()
- : "";
- if (rawText) {
- pieces.push(
- `${escapeHtml(rawText)}
`
- );
- } else {
- pieces.push(
- '未识别到文本
'
- );
- }
-
- const segments = Array.isArray(data && data.segments)
- ? data.segments
- : [];
- if (segments.length) {
- const rendered = segments
- .map((segment) => {
- const start = formatSeconds(
- segment && segment.start
- );
- const end = formatSeconds(segment && segment.end);
- const caption =
- segment && segment.text
- ? segment.text.trim()
- : "";
- return `${escapeHtml(
- start
- )} - ${escapeHtml(end)}${escapeHtml(
- caption
- )}
`;
- })
- .join("");
- pieces.push(
- `${rendered}
`
- );
- }
-
- const meta = [];
- if (data && data.language) {
- meta.push(`语言: ${escapeHtml(String(data.language))}`);
- }
- if (
- data &&
- typeof data.duration === "number" &&
- isFinite(data.duration) &&
- data.duration > 0
- ) {
- meta.push(
- `音频: ${escapeHtml(formatSeconds(data.duration))}`
- );
- }
- if (meta.length) {
- pieces.push(
- `${meta.join(" · ")}
`
- );
- }
-
- return pieces.join("");
- }
-
- function formatSeconds(value) {
- const num = Number(value);
- if (!isFinite(num) || num <= 0) {
- return "0s";
- }
- if (num >= 60) {
- const m = Math.floor(num / 60);
- const s = Math.round(num % 60);
- return `${m}m${s < 10 ? "0" : ""}${s}s`;
- }
- if (num < 1) {
- return `${num.toFixed(2)}s`;
- }
- return `${Math.round(num)}s`;
- }
-
- document.addEventListener("click", (event) => {
- const btn = event.target.closest(".voice-stt-btn");
- if (!btn) return;
- if (
- window.ChatlogSpeech &&
- typeof window.ChatlogSpeech.requestVoice === "function"
- ) {
- return;
- }
- event.preventDefault();
- fallbackVoiceRequest(btn);
- });
-
const diaryDateInput = document.getElementById("diary-date");
if (diaryDateInput) {
const today = new Date();
diff --git a/internal/speech/whispercpp/transcriber.go b/internal/speech/whispercpp/transcriber.go
index 0b4cc5d..7a2b069 100644
--- a/internal/speech/whispercpp/transcriber.go
+++ b/internal/speech/whispercpp/transcriber.go
@@ -1,11 +1,5 @@
-//go:build cgo
-
package whispercpp
-/*
-#cgo CFLAGS: -I${SRCDIR}/../../../third_party/whisper/include
-#cgo LDFLAGS: -L${SRCDIR}/../../../third_party/whisper/lib -lwhisper -lggml -lstdc++ -lm
-*/
import "C"
import (
diff --git a/third_party/whisper/lib/libggml.a b/third_party/whisper/lib/libggml.a
new file mode 100644
index 0000000000000000000000000000000000000000..3c287238ce84a3d280cdc8ead95c7fb2fab575fa
GIT binary patch
literal 69486
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%0D_{QWwY?5%t`Y`d2A*H3N
zrK^1{waxz62rLXyL|}DWTts6_Bff2tItKUpl5$GS!s3(|LsHeX;uA2joOE!K!jZg5
zlIY;%NwD@s{T3F3;%iA3#&l$oJ7>l4(EggZj_SUwkdC{@RF{DbOP0p*fsma&S-rDS=ZZ5VS
ztaw{%qG`AO2+aRm0IF4sV*hUeNHme6StKqG*jGgUFIvhu)`gV+jrXW@DV9*$Zj=jEYyk0!yJfDJC5CdoF*nJreB%R?+!iNNC?)P@IYPm8u=60v?kK3i
zJH>5nVU;?Pq#F2Uw-V-vM5%7~rZ5Fk@-d7v*yxTuX(}NT?#5IMWZg-qk9F$e^EEcN
z`R26y{a(3afjb@)vIyVurSB3~;nS}w$cvRVMRc(Wn(Gf#x3|`n)z`QC@sP754YW43
zuEJWAT!92UI-C4+@P?`RSc5}aTJ}RfM9&P=E^S=t!JaH%9kvE`@LHU&v8ADv%O6XX
zj}#q^gCX?zd@GxiQTmp3b@|%xMb_4q+NQ?9Y9GGZs%{<)Y=!0deESZ@3L#|6CZ5z-
zhC2`Z^=7OFp;Tyg`oq8ZSbb@%qx%w#Ez2rb!D2jh%WKk+l1{R+!1McplPhj{iYFX9TQtw;n@94yGC}hU$CYb|e
z6PxbyV%gAB;H$(vIP6(%!jmTLbxjr3^RaDeI)|d3P>r=dtW)80(gA$UT7UMM6;j|^
zlJ6;6=5O)0qbx+RthJpUlNd-{b@A$|BX!j!QP-f||7?$JeM?b6DRZnK^>7tn>6Mzo
z0JWTwNqi;n!!$`o|B0?jZi=vm*(Q{>8_-_kHJ#kY&d#qOv*H~F1G-R8L4B*QxwgwE
zc73chR0K!Rc(uP`H8%*FIuDp@5i;e6OroCd*w|96Vz-bD)h$}e4>So`3S8a4aeHJki=ryO?YUBcSjo>
zs;{oOEzp4kF*jgHk97B*YKzpwk)n$Py2P6?l$vg%B=Y169jHO3)aDFWslRW@vXGWB&wJp$y8xR%MiC!v&U-u-*quwu7oFa*>D=456vpEbz%Ui4)sGGsEg};dlHM1mzYHO1`Ni+0vOBp&_DQsn84WmCxT`x>rzXX+uUE-?w
zrDO^>+}u{%j{e-Dj+FqDhtBqPY@O#jIn^sLQBrT2;Hc!`ISE&&>=nVF}WyzRfQ1JaUVxjp6?b-98$C
literal 0
HcmV?d00001