Skip to content

Commit

Permalink
Add Support for 320x240 Video Playback via mplayer (#117)
Browse files Browse the repository at this point in the history
Support for displaying videos in 320x240 resolution via mplayer:

* New command: mister.video %video%.

%video% can be a URL or a path, in either case, viewing is done by RAM cache.

Based on previous work by @mrchrisster and @wizzomafizzo.
  • Loading branch information
spark2k06 authored Nov 27, 2024
1 parent 9790f72 commit c6a55c4
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 0 deletions.
23 changes: 23 additions & 0 deletions pkg/launcher/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/wizzomafizzo/tapto/pkg/service/tokens"
"net/url"
"os"
"os/exec"
"path/filepath"
"strings"

Expand Down Expand Up @@ -57,6 +58,7 @@ 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 @@ -218,3 +220,24 @@ 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
}


89 changes: 89 additions & 0 deletions pkg/platforms/mister/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ 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 @@ -24,6 +25,94 @@ 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
`



)

func UserConfigToMrext(cfg *config.UserConfig) *mrextConfig.UserConfig {
Expand Down
19 changes: 19 additions & 0 deletions pkg/platforms/mister/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ 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
35 changes: 35 additions & 0 deletions pkg/service/readers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/wizzomafizzo/tapto/pkg/service/tokens"
"strings"
"time"
"os/exec"

"github.com/rs/zerolog/log"
"github.com/wizzomafizzo/tapto/pkg/config"
Expand Down Expand Up @@ -125,6 +126,39 @@ func connectReaders(
return nil
}

func stopMPlayer() {
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
}

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)
}
}
}


func readerManager(
pl platforms.Platform,
cfg *config.UserConfig,
Expand Down Expand Up @@ -270,6 +304,7 @@ func readerManager(
} else {
log.Info().Msg("token was removed")
st.SetActiveCard(tokens.Token{})
stopMPlayer()
if shouldExit(cfg, pl, st) {
startTimedExit()
}
Expand Down

0 comments on commit c6a55c4

Please sign in to comment.