Skip to content

Commit

Permalink
MiSTer video support improvements (#120)
Browse files Browse the repository at this point in the history
* Initial video support refactor

* Improve path matching functions

* Add video metadata

* Fix indexing zips bug

* Improvements to mplayer launcher
  • Loading branch information
wizzomafizzo authored Dec 12, 2024
1 parent c6a55c4 commit 5ff9da7
Show file tree
Hide file tree
Showing 14 changed files with 329 additions and 217 deletions.
7 changes: 7 additions & 0 deletions pkg/assets/systems/Video.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"id": "Video",
"name": "Video",
"category": "Other",
"releaseDate": "1888-01-01",
"manufacturer": "N/A"
}
2 changes: 1 addition & 1 deletion pkg/database/gamesdb/gamesdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func NewNamesIndex(
update(status)

for _, path := range systemPaths[k] {
pathFiles, err := GetFiles(platform, k, path)
pathFiles, err := GetFiles(cfg, platform, k, path)
if err != nil {
return status.Files, fmt.Errorf("error getting files: %s", err)
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/database/gamesdb/indexing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gamesdb

import (
"fmt"
"github.com/wizzomafizzo/tapto/pkg/config"
"io/fs"
"os"
"path/filepath"
Expand Down Expand Up @@ -108,6 +109,7 @@ func (r *resultsStack) get() (*[]string, error) {
// files. This function deep searches .zip files and handles symlinks at all
// levels.
func GetFiles(
cfg *config.UserConfig,
platform platforms.Platform,
systemId string,
path string,
Expand Down Expand Up @@ -195,14 +197,14 @@ func GetFiles(
}

for i := range zipFiles {
if platforms.MatchSystemFile(platform, (*system).Id, zipFiles[i]) {
abs := filepath.Join(path, zipFiles[i])
abs := filepath.Join(path, zipFiles[i])
if utils.MatchSystemFile(cfg, platform, (*system).Id, abs) {
*results = append(*results, abs)
}
}
} else {
// regular files
if platforms.MatchSystemFile(platform, (*system).Id, path) {
if utils.MatchSystemFile(cfg, platform, (*system).Id, path) {
*results = append(*results, path)
}
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/database/gamesdb/systems.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ const (
SystemArcade = "Arcade"
SystemArduboy = "Arduboy"
SystemChip8 = "Chip8"
SystemVideo = "Video"
)

var Systems = map[string]System{
Expand Down Expand Up @@ -511,4 +512,7 @@ var Systems = map[string]System{
SystemChip8: {
Id: SystemChip8,
},
SystemVideo: {
Id: SystemVideo,
},
}
23 changes: 0 additions & 23 deletions pkg/launcher/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"github.com/wizzomafizzo/tapto/pkg/service/tokens"
"net/url"
"os"
"os/exec"
"path/filepath"
"strings"

Expand Down Expand Up @@ -58,7 +57,6 @@ var commandMappings = map[string]func(platforms.Platform, platforms.CmdEnv) erro
"mister.core": forwardCmd,
"mister.script": forwardCmd,
"mister.mgl": forwardCmd,
"mister.video": cmdMisterVideo,

"http.get": cmdHttpGet,
"http.post": cmdHttpPost,
Expand Down Expand Up @@ -220,24 +218,3 @@ func LaunchToken(
CurrentIndex: currentIndex,
}), true
}

func cmdMisterVideo(pl platforms.Platform, env platforms.CmdEnv) error {
if len(env.Args) == 0 {
return fmt.Errorf("URL argument missing for mister.video command")
}

videoURL := env.Args
log.Info().Msgf("Playing video from URL: %s", videoURL)

cmd := exec.Command("tmp/tapto/vplay.sh", videoURL)

output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("error playing video: %v\nOutput: %s", err, output)
}

log.Info().Msg("Video playing successfully")
return nil
}


90 changes: 1 addition & 89 deletions pkg/platforms/mister/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const (
FailSoundFile = TempFolder + "/fail.wav"
SocketFile = TempFolder + "/tapto.sock"
PidFile = TempFolder + "/tapto.pid"
vplayFilePath = TempFolder + "/vplay.sh"
MappingsFile = "/media/fat/nfc.csv"
TokenReadFile = "/tmp/TOKENREAD"
ConfigFolder = mrextConfig.ScriptsConfigFolder + "/tapto"
Expand All @@ -25,94 +24,7 @@ const (
ArcadeDbFile = ConfigFolder + "/ArcadeDatabase.csv"
ScriptsFolder = mrextConfig.ScriptsFolder
CmdInterface = "/dev/MiSTer_cmd"
vplayContent = `#!/bin/bash
declare -g crtmode_640="video_mode=640,16,64,80,240,1,3,14,12380"
declare -g crtmode_320="video_mode=320,-16,32,32,240,1,3,13,5670"
# Read the contents of the INI file
declare -g ini_file="/media/fat/MiSTer.ini"
declare -g ini_contents=$(cat "$ini_file")
declare -g branch="main"
declare -g repository_url="https://github.com/mrchrisster/MiSTer_SAM"
function curl_download() { # curl_download ${filepath} ${URL}
curl \
--connect-timeout 15 --max-time 600 --retry 3 --retry-delay 5 --silent --show-error \
--insecure \
--fail \
--location \
-o "${1}" \
"${2}"
}
function get_mplayer() {
echo " Downloading wizzo's mplayer for SAM..."
echo " Created for MiSTer by wizzo"
echo " https://github.com/wizzomafizzo/mrext"
latest_mplayer="${repository_url}/blob/${branch}/.MiSTer_SAM/mplayer.zip?raw=true"
latest_mbc="${repository_url}/blob/${branch}/.MiSTer_SAM/mbc?raw=true"
curl_download "/tmp/tapto/mplayer.zip" "${latest_mplayer}"
curl_download "/tmp/tapto/mbc" "${latest_mbc}"
unzip -ojq /tmp/tapto/mplayer.zip -d "/tmp/tapto"
chmod +x /tmp/tapto/mplayer
chmod +x /tmp/tapto/mbc
rm /tmp/tapto/mplayer.zip
echo " Done."
}
if [ ! -f /tmp/tapto/mplayer ]; then
get_mplayer
fi
function mplayer() {
LD_LIBRARY_PATH=/tmp/tapto /tmp/tapto/mplayer "$@"
}
url=$1
res="$(mplayer -vo null -ao null -identify -frames 0 $url | grep "VIDEO:" | awk '{print $3}')"
res_comma=$(echo "$res" | tr 'x' ',')
res_space=$(echo "$res" | tr 'x' ' ')
function change_menures() {
# Backup mister.ini
if [ -f "$ini_file" ]; then
cp "$ini_file" "${ini_file}".vpl
else
touch "$ini_file"
fi
#append menu info
echo -e "\n[menu]" >> "$ini_file"
echo -e "$crtmode_320" >> "$ini_file"
echo "[menu] entry created."
# Replace video_mode if it exists within [menu] entry
if [[ $ini_contents =~ \[menu\].*video_mode=([^,[:space:]]+) ]]; then
awk -v res_comma="$res_comma" '/\[menu\]/{p=1} p&&/video_mode/{sub(/=.*/, "="res_comma",60"); p=0} 1' "$ini_file" > "$ini_file.tmp" && mv "$ini_file.tmp" "$ini_file"
echo "video_mode replaced in [menu] entry."
fi
}
## Play video
change_menures
echo load_core /media/fat/menu.rbf > /dev/MiSTer_cmd
sleep 2
# open mister terminal
/media/fat/Scripts/.MiSTer_SAM/mbc raw_seq :43
chvt 2
vmode -r ${res_space} rgb32
sleep 2
mplayer -cache 8192 "$url"
cp "$ini_file.vpl" "$ini_file"
echo load_core /media/fat/menu.rbf > /dev/MiSTer_cmd
`



LinuxFolder = "/media/fat/linux"
)

func UserConfigToMrext(cfg *config.UserConfig) *mrextConfig.UserConfig {
Expand Down
126 changes: 126 additions & 0 deletions pkg/platforms/mister/launchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
package mister

import (
"fmt"
"github.com/rs/zerolog/log"
"github.com/wizzomafizzo/mrext/pkg/games"
"github.com/wizzomafizzo/mrext/pkg/mister"
"github.com/wizzomafizzo/tapto/pkg/config"
"github.com/wizzomafizzo/tapto/pkg/database/gamesdb"
"github.com/wizzomafizzo/tapto/pkg/platforms"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)

func launch(cfg *config.UserConfig, path string) error {
Expand Down Expand Up @@ -49,7 +55,127 @@ func launchAltCore(
}
}

func killCore(_ *config.UserConfig) error {
return mister.LaunchMenu()
}

func launchMPlayer(pl Platform) func(*config.UserConfig, string) error {
return func(_ *config.UserConfig, path string) error {
if len(path) == 0 {
return fmt.Errorf("no path specified")
}

vt := "4"

if pl.ActiveSystem() != "" {

}

//err := mister.LaunchMenu()
//if err != nil {
// return err
//}
//time.Sleep(3 * time.Second)

err := cleanConsole(vt)
if err != nil {
return err
}

err = openConsole(pl.kbd, vt)
if err != nil {
return err
}

time.Sleep(500 * time.Millisecond)
err = mister.SetVideoMode(640, 480)
if err != nil {
return fmt.Errorf("error setting video mode: %w", err)
}

cmd := exec.Command(
"nice",
"-n",
"-20",
filepath.Join(LinuxFolder, "mplayer"),
"-cache",
"8192",
path,
)
cmd.Env = append(os.Environ(), "LD_LIBRARY_PATH="+LinuxFolder)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

restore := func() {
err := mister.LaunchMenu()
if err != nil {
log.Warn().Err(err).Msg("error launching menu")
}

err = restoreConsole(vt)
if err != nil {
log.Warn().Err(err).Msg("error restoring console")
}
}

err = cmd.Start()
if err != nil {
restore()
return err
}

err = cmd.Wait()
if err != nil {
restore()
return err
}

restore()
return nil
}
}

func killMPlayer(_ *config.UserConfig) error {
psCmd := exec.Command("sh", "-c", "ps aux | grep mplayer | grep -v grep")
output, err := psCmd.Output()
if err != nil {
log.Info().Msgf("mplayer processes not detected.")
return nil
}

lines := strings.Split(string(output), "\n")
for _, line := range lines {
if line == "" {
continue
}

log.Debug().Msgf("processing line: %s", line)

fields := strings.Fields(line)
if len(fields) < 2 {
log.Warn().Msgf("unexpected line format: %s", line)
continue
}

pid := fields[0]
log.Info().Msgf("killing mplayer process with PID: %s", pid)

killCmd := exec.Command("kill", "-9", pid)
if err := killCmd.Run(); err != nil {
log.Error().Msgf("failed to kill process %s: %v", pid, err)
}
}

return nil
}

var Launchers = []platforms.Launcher{
{
Id: "Generic",
Extensions: []string{".mgl", ".rbf", ".mra"},
Launch: launch,
},
// Consoles
{
Id: gamesdb.SystemAdventureVision,
Expand Down
19 changes: 0 additions & 19 deletions pkg/platforms/mister/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,6 @@ func Setup(tr *Tracker) error {
}
_ = ff.Close()

vplayFile, err := os.Create(vplayFilePath)
if err != nil {
log.Error().Msgf("error creating vplay.sh file: %s", err)
return err
}

_, err = vplayFile.WriteString(vplayContent)
if err != nil {
log.Error().Msgf("error writing to vplay.sh file: %s", err)
return err
}
_ = vplayFile.Close()

err = os.Chmod(vplayFilePath, 0755)
if err != nil {
log.Error().Msgf("error setting executable permissions for vplay.sh: %s", err)
return err
}

// attempt arcadedb update
go func() {
haveInternet := utils.WaitForInternet(30)
Expand Down
Loading

0 comments on commit 5ff9da7

Please sign in to comment.