Golang中实现这个功能的简单方法有哪些
Golang中实现这个功能的简单方法有哪些 你好。
我找到了这个程序(GitHub - raitonoberu/sptlrx: 在终端中显示时间同步的歌词),它的功能完全符合我的需求,只不过……它是用在终端里的,而我想要让它在一个本地网页上运行。
我喜欢和我的家人朋友一起唱歌,我正在一个树莓派上搭建一个(差不多算是)高保真音响系统,使用 Mopidy 和 Qobuz。
所以,我想知道这是否可行,我的意思是,我需要学习什么才能让那个程序在一个本地网页上工作?我指的是让歌词显示在一个简单的本地网页上,不需要花哨的功能,就像在终端里那样。
我需要修改什么,在代码的哪个部分……进行修改?
更多关于Golang中实现这个功能的简单方法有哪些的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中实现这个功能的简单方法有哪些的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
要实现将终端歌词显示功能迁移到本地网页,以下是几种Golang实现方案:
方案一:使用标准库net/http创建Web服务器
package main
import (
"fmt"
"net/http"
"time"
)
type LyricsLine struct {
Time int `json:"time"`
Text string `json:"text"`
}
var currentLyrics []LyricsLine
var currentIndex int
func lyricsHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
return
}
// 模拟歌词推送
for {
if currentIndex < len(currentLyrics) {
fmt.Fprintf(w, "data: %s\n\n", currentLyrics[currentIndex].Text)
flusher.Flush()
currentIndex++
}
time.Sleep(2 * time.Second)
}
}
func main() {
// 初始化示例歌词数据
currentLyrics = []LyricsLine{
{Time: 0, Text: "第一行歌词"},
{Time: 5, Text: "第二行歌词"},
{Time: 10, Text: "第三行歌词"},
}
http.HandleFunc("/lyrics", lyricsHandler)
http.Handle("/", http.FileServer(http.Dir("./static")))
fmt.Println("服务器启动在 http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
方案二:使用WebSocket实时同步歌词
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // 允许所有来源(仅限本地使用)
},
}
func websocketHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("WebSocket升级失败:", err)
return
}
defer conn.Close()
// 从原程序获取歌词数据并发送
for {
// 这里需要集成原程序的歌词获取逻辑
lyricsLine := getCurrentLyrics() // 假设的函数
err := conn.WriteJSON(lyricsLine)
if err != nil {
log.Println("发送失败:", err)
break
}
}
}
func getCurrentLyrics() map[string]interface{} {
// 这里实现从原程序获取当前歌词的逻辑
return map[string]interface{}{
"text": "当前歌词",
"time": 12345,
}
}
func main() {
http.HandleFunc("/ws", websocketHandler)
http.Handle("/", http.FileServer(http.Dir("./web")))
log.Println("服务器启动: http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
方案三:集成原程序的核心逻辑
package main
import (
"encoding/json"
"net/http"
"sync"
"time"
)
type LyricsServer struct {
mu sync.RWMutex
lyrics []string
current string
position time.Duration
}
func (ls *LyricsServer) updateLyrics() {
// 这里需要修改原程序的歌词获取逻辑
// 将原来的终端输出改为更新内部状态
ls.mu.Lock()
defer ls.mu.Unlock()
// 模拟更新
ls.current = "更新的歌词"
ls.position = time.Second * 30
}
func (ls *LyricsServer) getCurrent() map[string]interface{} {
ls.mu.RLock()
defer ls.mu.RUnlock()
return map[string]interface{}{
"lyrics": ls.current,
"position": ls.position.Seconds(),
}
}
func main() {
server := &LyricsServer{}
http.HandleFunc("/api/lyrics", func(w http.ResponseWriter, r *http.Request) {
data := server.getCurrent()
json.NewEncoder(w).Encode(data)
})
// 静态文件服务
fs := http.FileServer(http.Dir("public"))
http.Handle("/", fs)
// 启动歌词更新循环
go func() {
ticker := time.NewTicker(100 * time.Millisecond)
for range ticker.C {
server.updateLyrics()
}
}()
http.ListenAndServe(":8080", nil)
}
前端HTML示例(保存为static/index.html)
<!DOCTYPE html>
<html>
<head>
<title>歌词显示</title>
<style>
#lyrics {
font-size: 2em;
text-align: center;
margin-top: 20%;
font-family: monospace;
}
</style>
</head>
<body>
<div id="lyrics">等待歌词...</div>
<script>
// 使用EventSource
const evtSource = new EventSource("/lyrics");
evtSource.onmessage = function(event) {
document.getElementById("lyrics").textContent = event.data;
};
evtSource.onerror = function() {
console.log("连接错误");
};
</script>
</body>
</html>
需要修改原程序的部分:
- 数据输出层:将原程序的终端输出改为Web API输出
- 时间同步逻辑:保持原有的时间同步机制,改为通过HTTP或WebSocket发送
- 歌词解析:复用原有的歌词解析模块,只改变输出方式
关键修改点通常在:
- 主循环中的显示部分
- 时间同步回调函数
- 歌词更新触发机制
将原有的fmt.Println或终端输出函数调用替换为向Web客户端发送数据的逻辑即可。

