Closed fire-hawk-86 closed 1 year ago
There are still bugs with it:
If the video is paused before exiting, Mplayer will crash/quit on next launch, and not be able to resume.
When the video finishes playing and Mplayer automatically exits, the resume file is not removed.
First bug fixed:
#!/bin/sh
RESUME=$(dirname "$1")/.$(basename "$1").resume
EXIT=$(tail -n 1 "$RESUME")
PAUSED=$(tail -n 3 "$RESUME" | grep -c "PAUSE")
if [ -f "$RESUME" ] && [ "$EXIT" == "Exiting... (Quit)" ]; then
if [ "$PAUSED" == 1 ]; then
END=$(cat -v "$RESUME" | tail -4 | head -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
else
END=$(cat -v "$RESUME" | tail -3 | head -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
fi
./mplayer -ss $END -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee "$RESUME"
else
./mplayer -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee "$RESUME"
fi
EXIT=$(tail -n 1 "$RESUME")
if [ "$EXIT" == "Exiting... (Quit)" ]; then
#echo "Quit"
elif [ "$EXIT" == "Exiting... (End of file)" ]; then
#echo "End"
rm "$RESUME"
else
#echo "Broken"
rm "$RESUME"
fi
Add a :
below #echo "Quit"
.
if [ "$EXIT" == "Exiting... (Quit)" ]; then
#echo "Quit"
:
That's where the elif
bug comes from, because it expects at least one command.
The :
functions as a placeholder command, that is not doing anything.
This is one of the reasons why the .resume
files weren't deleted.
The shell script doesn't even get that far, because of that error.
You're correct! :smiley:
The following code fixes both bugs:
#!/bin/sh
RESUME=$(dirname "$1")/.$(basename "$1").resume
EXIT=$(tail -n 1 "$RESUME")
PAUSED=$(tail -n 3 "$RESUME" | grep -c "PAUSE")
if [ -f "$RESUME" ] && [ "$EXIT" == "Exiting... (Quit)" ]; then
if [ "$PAUSED" == 1 ]; then
END=$(cat -v "$RESUME" | tail -4 | head -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
else
END=$(cat -v "$RESUME" | tail -3 | head -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
fi
./mplayer -ss $END -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee "$RESUME"
else
./mplayer -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee "$RESUME"
fi
EXIT=$(tail -n 1 "$RESUME")
if [ "$EXIT" == "Exiting... (Quit)" ]; then
#echo "Quit"
:
elif [ "$EXIT" == "Exiting... (End of file)" ]; then
#echo "End"
rm "$RESUME"
else
#echo "Broken"
rm "$RESUME"
fi
It can actually be simplified with:
#!/bin/sh
RESUME=$(dirname "$1")/.$(basename "$1").resume
EXIT=$(tail -n 1 "$RESUME")
PAUSED=$(tail -n 3 "$RESUME" | grep -c "PAUSE")
if [ -f "$RESUME" ] && [ "$EXIT" == "Exiting... (Quit)" ]; then
if [ "$PAUSED" == 1 ]; then
END=$(cat -v "$RESUME" | tail -4 | head -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
else
END=$(cat -v "$RESUME" | tail -3 | head -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
fi
./mplayer -ss $END -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee "$RESUME"
else
./mplayer -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee "$RESUME"
fi
EXIT=$(tail -n 1 "$RESUME")
if [ "$EXIT" != "Exiting... (Quit)" ]; then
rm "$RESUME"
fi
Since we don't need to keep the resume file if the playback was not in progress and properly saved.
Hmm... :thinking: Wouldn't it be simpler and more reliable to simply grep
for the line with the last instance of "V:" instead of using tail
to try and guess where the line is located in the file?
$(grep "V:" "$RESUME" | tail -n 1)
This would allow us to resume playback even if a clean shutdown didn't take place -- if the resume file is corrupted.
Here is a more forwards-compatible and better documented and optimised version of this script. One that doesn't continually write to the SD card as you're watching (prolonging your SD card's life):
#!/bin/sh
# Set resume file path
RESUMEFILE=$(dirname "$1")/.$(basename "$1").resume
# Get resume states from resume file
RESUMES=$(cat -v "$RESUMEFILE" | grep " V:")
# Set resume time
START=00:00:00
if [ -f "$RESUMEFILE" ] && [ "$RESUMES" != "" ]; then
START=$(echo "$RESUMES" | tail -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
fi
unset RESUMES
# Start playback
RESUMESTATE=$(./mplayer -ss $START -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee /dev/tty)
# Check whether to save state on exit
SAVEVALID=false
SAVECOND=$(echo "$RESUMESTATE" | grep -c "Exiting... (Quit)")
#SAVECOND=$(echo "$RESUMESTATE" | grep -c "End of file")
if [ "$SAVECOND" != 0 ]; then
SAVEVALID=true
fi
# Save resume state, or remove save file
if [ "$SAVEVALID" == true ]; then
echo "$RESUMESTATE" > "$RESUMEFILE"
elif [ -f "$RESUMEFILE" ]; then
rm "$RESUMEFILE"
fi
unset RESUMESTATE
It's set to save the resume state whenever you quit Mplayer (until you've reached the end of the video).
Alternatively, if you want Mplayer to save the resume state on every single occasion (even when it force-quits or crashes) except when you've reached the end of the file (finished watching the video), then swap the SAVEVALID and SAVECOND values in this section, like so:
# Check whether to save state on exit
SAVEVALID=true
#SAVECOND=$(echo "$RESUMESTATE" | grep -c "Exiting... (Quit)")
SAVECOND=$(echo "$RESUMESTATE" | grep -c "End of file")
if [ "$SAVECOND" != 0 ]; then
SAVEVALID=false
fi
Mplayer is now able to resume playback even from a badly/differently formatted resume save (so long as the timestamps are there).
I've recently encoded a couple of movies for the PocketGo. But sadly they the audio and video were going out of sync constantly, then you have to "fast forward" or "rewind" to fix it, until it goes out of sync again. This issue seems to be fixed completely now.
I think that had to do with the constant writing to the .resume
file, before the fix.
Thanks.
Could be -- the continuous writing to the SD card would also impose a throttle on the read-write (data transfer) speed of the card, and how much data can pass through at once.
Also, use these settings when converting videos for Miyoo:
Encoding: MPEG-4 Resolution: 320x240 (240p) Video Bitrate: 1024 (or less) kbps Framerate: 20 fps
See here for guidance/tips: https://github.com/TriForceX/MiyooCFW/discussions/351
For anyone using and testing this script (the latter one), I'd be interested to hear how it performs on lengthier videos, over 2 hours long. There is one potential drawback with this method, and that is that the resume state is being stored in the RAM until Mplayer exits, and that there's a limit to how much data can be stored in memory.
I'm pretty certain it will hold up fine, but, nonetheless, I'd be interested to hear if anyone notices any issues with very long audios or videos.
Okay, I've just tested a 2 and a half hour long, 1.3 GB size film. These are my experiences/observations:
When starting the video, Mplayer stutters for about 15-30 seconds, until it loads the massive stream, at which point the video quickly attempts to catch up with the current time in the playback by fast-forwarding to it. Fortunately, this is the space usually occupied by the movie studio logos we're all well familiar with and have seen a million times. After this initial stutter, the video plays fine as expected, and perfectly in sync with the audio.
After about 50 minutes into the film, I experienced an apparent stop/freeze in playback, but it looks like this was caused by my device's battery running low and the associated alert event. I was able to exit Mplayer without issue, and upon reloading the film, it continued right from where it left off -- the resume file had been successfully saved and was loaded without issue. Following that (and the initial 15-30 second stutter again, until the massive stream loaded), the movie continued to play as normal, because the memory had been dumped to disk and freed upon closing Mplayer. š
(Considering we're working with only 32 MB of RAM here as the only available system memory, that's not bad at all!)
50 minutes of watching a film produced about 3 MB of save data (which was successfully written to disk). Therefore watching a 2.5 hour long film, if the device can handle the whole thing in one session, will produce about 9 MB of save data in Mplayer (to be stored in memory and written to the disk).
Upon relaunching the movie, the other 100 minutes of it played perfectly, without any issues whatsoever -- confirming my suspicion that the stop/freeze was due to the battery alert, not due to any memory issues.
At the movie credits, I exited and saved the play progress. It took a little while to save -- a 5.5 MB resume save file was created, which was successfully loaded by the script upon launching the movie again. Mplayer resumed playback from the credits. šš
Upon reaching the end of the video, the resume save file was automatically removed, and the memory cleared again as Mplayer exited. š
If anyone has any other experiences, let me know.
Here's an update to the script to add audio file resume support as well (when there's no video to play):
#!/bin/sh
# Set resume file path
RESUMEFILE=$(dirname "$1")/.$(basename "$1").resume
# Get resume states from resume file
RESUMES=$(cat -v "$RESUMEFILE" | grep "A:")
NOVIDEO=$(cat -v "$RESUMEFILE" | grep -c "no video")
# Set resume time
START=00:00:00
if [ -f "$RESUMEFILE" ] && [ "$RESUMES" != "" ]; then
if [ "$NOVIDEO" != 0 ]; then
START=$(echo "$RESUMES" | tail -1 | sed 's/.*A://' | cut -d"(" -f1 | xargs)
else
START=$(echo "$RESUMES" | tail -1 | sed 's/.*\ V://' | cut -dA -f1 | xargs)
fi
fi
unset RESUMES
# Start playback
RESUMESTATE=$(./mplayer -ss $START -ao alsa -vo sdl -vf scale -zoom -xy 320 -screenw 320 -screenh 240 "$1" | tee /dev/tty)
# Check whether to save state on exit
SAVEVALID=false
SAVECOND=$(echo "$RESUMESTATE" | grep -c "Exiting... (Quit)")
#SAVECOND=$(echo "$RESUMESTATE" | grep -c "End of file")
if [ "$SAVECOND" != 0 ]; then
SAVEVALID=true
fi
# Save resume state, or remove save file
if [ "$SAVEVALID" == true ]; then
echo "$RESUMESTATE" > "$RESUMEFILE"
elif [ -f "$RESUMEFILE" ]; then
rm "$RESUMEFILE"
fi
unset RESUMESTATE
Mplayer can now be used to listen to audiobooks as well (and save progress).
thank you - It seems to be working for me - very much appreciated
It does not only check if there is a
.resume
file, but also, if the file is valid. If it's invalid, it will play the video from the start, just as if there was none. If the video is finished, and an invalid.resume
file is produced, it will be deleted, just as if it was a legit(End of file)
.Explanation: At the end of a video, the return value of
mplayer
isn't producing the expected output withExiting... (End of file)
as the last line.I tested it and it works as expected. You don't even have to delete any
.resume
files manually.edit
main/apps/mplayer/run.sh
on your sd-card to the followingEnjoy!