mirror of
https://github.com/Apologieze/Benri.git
synced 2026-01-18 17:17:21 +01:00
198 lines
4.6 KiB
Go
198 lines
4.6 KiB
Go
package curdInteg
|
|
|
|
import (
|
|
// "fmt"
|
|
"crypto/rand"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/charmbracelet/log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
)
|
|
|
|
var logFile = "debug.log"
|
|
|
|
func getMPVPath() (string, error) {
|
|
exePath, err := os.Executable()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
exeDir := filepath.Dir(exePath)
|
|
mpvPath := filepath.Join(exeDir, "bin", "mpv.exe") // Adjust the relative path
|
|
return mpvPath, nil
|
|
}
|
|
|
|
func StartVideo(link string, args []string, title string) (string, error) {
|
|
var command *exec.Cmd
|
|
|
|
// Generate a random number for the socket path
|
|
randomBytes := make([]byte, 4)
|
|
_, err := rand.Read(randomBytes)
|
|
if err != nil {
|
|
log.Error("Failed to generate random number")
|
|
return "", fmt.Errorf("failed to generate random number: %w", err)
|
|
}
|
|
|
|
randomNumber := fmt.Sprintf("%x", randomBytes)
|
|
|
|
// Create the mpv socket path with the random number
|
|
var mpvSocketPath string
|
|
if runtime.GOOS == "windows" {
|
|
mpvSocketPath = fmt.Sprintf(`\\.\pipe\curd_mpvsocket_%s`, randomNumber)
|
|
} else {
|
|
mpvSocketPath = fmt.Sprintf("/tmp/curd_mpvsocket_%s", randomNumber)
|
|
}
|
|
|
|
// Add the title to MPV arguments
|
|
titleArgs := []string{fmt.Sprintf("--title=%s", title), fmt.Sprintf("--force-media-title=%s", title)}
|
|
args = append(args, titleArgs...)
|
|
|
|
// Prepare arguments for mpv
|
|
var mpvArgs []string
|
|
mpvArgs = append(mpvArgs, "--no-terminal", "--really-quiet", fmt.Sprintf("--input-ipc-server=%s", mpvSocketPath), link)
|
|
// Add any additional arguments passed
|
|
if len(args) > 0 {
|
|
mpvArgs = append(mpvArgs, args...)
|
|
}
|
|
|
|
if runtime.GOOS == "windows" {
|
|
// Get the path to mpv.exe for Windows
|
|
mpvPath, err := getMPVPath()
|
|
if err != nil {
|
|
CurdOut("Error: Failed to get MPV path")
|
|
log.Error("Failed to get mpv path.")
|
|
return "", err
|
|
}
|
|
|
|
// Create command for Windows
|
|
command = exec.Command(mpvPath, mpvArgs...)
|
|
} else {
|
|
// Create command for Unix-like systems
|
|
command = exec.Command("mpv", mpvArgs...)
|
|
}
|
|
|
|
// Start the mpv process
|
|
err = command.Start()
|
|
if err != nil {
|
|
CurdOut("Error: Failed to start mpv process")
|
|
return "", fmt.Errorf("failed to start mpv: %w", err)
|
|
}
|
|
return mpvSocketPath, nil
|
|
}
|
|
|
|
// Helper function to join args with a space
|
|
func joinArgs(args []string) string {
|
|
result := ""
|
|
for i, arg := range args {
|
|
if i > 0 {
|
|
result += " "
|
|
}
|
|
result += arg
|
|
}
|
|
return result
|
|
}
|
|
|
|
func MPVSendCommand(ipcSocketPath string, command []interface{}) (interface{}, error) {
|
|
conn, err := connectToPipe(ipcSocketPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer conn.Close()
|
|
|
|
commandStr, err := json.Marshal(map[string]interface{}{
|
|
"command": command,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Send the command
|
|
_, err = conn.Write(append(commandStr, '\n'))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Receive the response
|
|
buf := make([]byte, 4096)
|
|
n, err := conn.Read(buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var response map[string]interface{}
|
|
if err := json.Unmarshal(buf[:n], &response); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if data, exists := response["data"]; exists {
|
|
return data, nil
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func SeekMPV(ipcSocketPath string, time int) (interface{}, error) {
|
|
command := []interface{}{"seek", time, "absolute"}
|
|
return MPVSendCommand(ipcSocketPath, command)
|
|
}
|
|
|
|
func GetMPVPausedStatus(ipcSocketPath string) (bool, error) {
|
|
status, err := MPVSendCommand(ipcSocketPath, []interface{}{"get_property", "pause"})
|
|
if err != nil || status == nil {
|
|
return false, err
|
|
}
|
|
|
|
paused, ok := status.(bool)
|
|
if ok {
|
|
return paused, nil
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func GetMPVPlaybackSpeed(ipcSocketPath string) (float64, error) {
|
|
speed, err := MPVSendCommand(ipcSocketPath, []interface{}{"get_property", "speed"})
|
|
if err != nil || speed == nil {
|
|
log.Error("Failed to get playback speed.", logFile)
|
|
return 0, err
|
|
}
|
|
|
|
currentSpeed, ok := speed.(float64)
|
|
if ok {
|
|
return currentSpeed, nil
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
func GetPercentageWatched(ipcSocketPath string) (float64, error) {
|
|
currentTime, err := MPVSendCommand(ipcSocketPath, []interface{}{"get_property", "time-pos"})
|
|
if err != nil || currentTime == nil {
|
|
return 0, err
|
|
}
|
|
|
|
duration, err := MPVSendCommand(ipcSocketPath, []interface{}{"get_property", "duration"})
|
|
if err != nil || duration == nil {
|
|
return 0, err
|
|
}
|
|
|
|
currTime, ok1 := currentTime.(float64)
|
|
dur, ok2 := duration.(float64)
|
|
|
|
if ok1 && ok2 && dur > 0 {
|
|
percentageWatched := (currTime / dur) * 100
|
|
return percentageWatched, nil
|
|
}
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
func PercentageWatched(playbackTime int, duration int) float64 {
|
|
if duration > 0 {
|
|
percentage := (float64(playbackTime) / float64(duration)) * 100
|
|
return percentage
|
|
}
|
|
return float64(0)
|
|
}
|