Relies on some *nix CLI utilities: mediainfo
; and qt-faststart
(part of ffmpeg
). I used homebrew to install them on OS X.
Pseudo streaming is simply a video that can start playing before it's fully dowmloaded. The videos are not streaming but rather progressively downloaded. What's important is that the file metadata (the Moov Atom) is at the start of the file rather than at the end. Usually this is an option set when encoding the file (called quick start or web start). If the files have not been encoded this way you can either re-encode or use a utility to move the Moov Atom. Re-encoding takes much longer than using a utility to move the Moov Atom so here's how to do it.
First check with mediainfo
to see if video 'is streamable':
mediainfo "--Inform=General;IsStreamable: %IsStreamable%" Video.mp4
Batch version to check with mediainfo
if the videos are streamable (i.e the Moov Atoms are at the start of the files):
find . -name "*.m*" -type f | (while read FN ; do echo mediainfo "--Inform=General;IsStreamable: %IsStreamable%" "$FN"; done)
If the output is IsStreamable: No
then you can use qt-faststart
(a utility in ffmpeg
) to move the Moov Atom.
Example qt-faststart
command:
qt-faststart video.mp4 video-NEW.mp4
__Note:__This command creates a new video file.
Run qt-faststart
with a batch command to convert a folder of videos:
for FILE in `find . -type f ` ; do NEWFILE=`echo "$FILE" | sed 's/.mov/_NEW.mov/g'` ; qt-faststart "$FILE" $NEWFILE ; done
__Note:__This command creates new video files.
A better approach would be to write the video files to a temp video and then replace it. However this works pretty well and I know how to do it this way.
First list the old files by inverse grepping (i.e. doesn't contain '_NEW')
ls | grep -v '_NEW'
If that lists the files you want to delete then delete the old files.
for FILE in `ls | grep -v '_NEW'` ; do rm $FILE ; done
Then rename files back to original by removing the '_NEW' at the end of the file name
for FILE in `find . -type f ` ; do NEWFILE=`echo "$FILE" | sed 's/_NEW.mov/.mov/g'` ; mv "$FILE" $NEWFILE ; done
Spaces can be problematic on *nix so I find it easier to remove them perform the programatic operation and put them back. There's probably a better way to deal with but this works for me.
- Double check control character isn't in the filename first
ls | grep '+'
- Replace spaces with a control character '+' :
for FILE in *.m* ; do NEWFILE=`echo $FILE | sed 's/ /+/g'` ; mv "$FILE" $NEWFILE ; done
- run qt-faststart
for FILE in `find . -type f ` ; do NEWFILE=`echo "$FILE" | sed 's/.mov/_NEW.mov/g'` ; qt-faststart "$FILE" $NEWFILE ; done
First list the old files by inverse grepping (but this works for me.doesn't contain '_NEW')
ls | grep -v '_NEW'
- If that lists the files you want to delete then delete the old files.
for FILE in `ls | grep -v '_NEW'` ; do rm $FILE ; done
- Then rename files back to original by removing the '_NEW' at the end of the file name
for FILE in `find . -type f ` ; do NEWFILE=`echo "$FILE" | sed 's/_NEW.mov/.mov/g'` ; mv "$FILE" $NEWFILE ; done
- Replace control character with spaces
for FILE in `find . -type f ` ; do NEWFILE=`echo "$FILE" | sed 's/+/ /g'` ; echo mv "$FILE" $NEWFILE ; done
Hello Mark,
Thanks for this nice set of recipes. I have a couple of remarks:
Your second example, the batch version, is IMHO incomplete. It lacks some string pattern next to the
echo
command. I achieved something useful with this command:find . -name "*.m*" -type f | (while read FN ; do echo "$FN: $(mediainfo "--Inform=General;IsStreamable: %IsStreamable%" "$FN")"; done)
Later in the page, you assume that the extension will be
.mov
, but it could also be.mp4
and.m4v
. I'm definitely not a shell guy, but if you see an easy way to work with any extension, I'll happily share it with you!Kind regards,
Dimitri