
Go 程序通过 Unix socket 向 mpv 发送 JSON 命令时需在 JSON 末尾添加换行符(\n),否则 mpv 无法解析指令;本文详解正确写法、原理及健壮性增强实践。
go 程序通过 unix socket 向 mpv 发送 json 命令时需在 json 末尾添加换行符(`\n`),否则 mpv 无法解析指令;本文详解正确写法、原理及健壮性增强实践。
mpv 的 IPC 接口(通过 --input-ipc-server=/tmp/mpvsocket 启动)采用行协议(line-based protocol):每条 JSON 命令必须以 \n(LF)结尾,服务端按行读取并解析。这与 socat 的行为一致——echo 默认输出带换行,因此命令行方式能成功;而原始 Go 代码中 c.Write([]byte(...)) 未附加换行符,导致 mpv 持续等待完整行输入,命令实际未被处理。
✅ 正确做法是在 JSON 字符串后显式追加 \n:
_, err = c.Write([]byte(`{"command":["quit"]}` + "\n"))
以下是完整、生产就绪的示例代码,已加入错误处理、连接超时和响应读取(可选):
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
package main
import (
"io"
"log"
"net"
"time"
)
func sendMPVCommand(socketPath, cmdJSON string) error {
// 设置连接超时,避免阻塞
dialer := &net.Dialer{Timeout: 3 * time.Second}
c, err := dialer.Dial("unix", socketPath)
if err != nil {
return log.Fatalf("failed to connect to mpv socket %s: %v", socketPath, err)
}
defer c.Close()
// 发送带换行的 JSON 命令(关键!)
_, err = c.Write([]byte(cmdJSON + "\n"))
if err != nil {
return log.Fatalf("write error: %v", err)
}
// (可选)读取 mpv 返回的响应(如 {"event":"client-message"} 或错误)
// 注意:quit 命令无响应,但其他命令如 get_property 可能返回结果
// resp, _ := io.ReadAll(c)
// log.Printf("mpv response: %s", string(resp))
return nil
}
func main() {
err := sendMPVCommand("/tmp/mpvsocket", `{"command":["quit"]}`)
if err != nil {
log.Fatal(err)
}
}
⚠️ 注意事项:
-
换行符不可省略:
"\n"是必需的,\r\n(CRLF)不被 mpv 支持; -
确保 mpv 已启用 IPC:启动时需指定
mpv --input-ipc-server=/tmp/mpvsocket your-video.mp4; -
权限与路径:确认 Go 进程对
/tmp/mpvsocket具有读写权限(Unix socket 文件权限由 mpv 进程创建时决定); - 并发安全:若需多命令连续发送,请确保每次写入后换行,并考虑加锁或使用独立连接(mpv 支持流水线,但响应顺序需自行管理);
-
JSON 格式严格:键名必须小写(如
"command"),数组结构需完整,推荐使用json.Marshal()构造动态命令以避免手写错误。
总结:Go 调用 Unix socket 与 mpv 交互的核心在于遵循其行协议规范——每条 JSON 命令必须以 \n 结尾。这一细节虽小,却是命令能否被正确识别的关键。结合超时控制与结构化封装,即可构建稳定可靠的 mpv 自动化控制程序。










