Automatically convert videos in Powerpoint file (pptx) to a different format
I have been trying to convert a lot of embedded videos in pptx files to a different format lately due to compatibility issues on some systems, but have not found an easy and fast way – so I wrote this bash script.
The goal was to have a pptx with videos that can be played using Powerpoint 2010 or later on Windows as well as OS X without plugins. That seems to only be the case for MPG videos (mpeg1video codec).
To convert videos in a presentation
- make sure that ffmpeg and a zip/unzip application is installed (ffmpeg can easily be replaced by avconv, but avconv somehow could not convert some files that were no problem for ffmpeg during my tests)
- download the bash file and make it executable
- edit the options at the beginning of the file, if you want to (mainly video output format and bitrate)
- Change to the directory with the pptx file(s) and start the conversion with /path/to/pptx_video_convert.sh myPresentation.pptx
- Check if everything worked by looking at myPresentation_converted.pptx or the logs
I’m not sure whether this will work with all pptx files. It assumes that videos are in the folder ppt/media , have the names media[0-9]*.EXT (EXT just being any extension) and are only directly referenced by files in ppt/slides/_rels .
The script does the following:
- unzip pptx
- transcode video files using ffmpeg
- update file references in ppt/slides/_rels
- add MIME type to [Content_Types].xml (especially this might go wrong)
- Rezip contents
#!/bin/bash
THREADS=4 # number of threads for ffmpeg
OUTPUT_VIDEO_FORMAT="mpeg1video" # -c:v parameter for ffmpeg
OUTPUT_VIDEO_BITRATE="4000k" # in bit/s
OUTPUT_VIDEO_FRAMERATE="25" # framerate in fps
OUTPUT_FILEEXTENSION="mpg" # note that this will also be added as MIME type to [Content_Types].xml in the format video/ext!
REMOVE_OLD_FILES=1 # remove old pptx files after conversion
if [ $# -ne 1 ]; then
echo 1>&2 "Usage: $0 PPTX_FILE"
exit
fi
FILE=$1
FOLDER="$FILE""_DIR"
mkdir -p "/tmp/pptx_conv/$FILE" # for log files
mkdir "$FOLDER"
cd "$FOLDER"
echo "--------------------"
echo "Unzipping <$FILE>..."
unzip ../"$FILE" > /dev/null
# convert video files
for OLD_NAME in ppt/media/media*.*
do
# cancel early if no video files are detected
if [ ! -e "$OLD_NAME" ]
then
echo "No video files detected"
cd ..
rm -rf "$FOLDER"
echo "Cleaned up. Did not create converted file, because there was nothing to convert."
echo "--------------------"
exit
fi
BASE_NAME=$(echo $OLD_NAME | cut -d "." -f1)
NEW_NAME=$BASE_NAME"."$OUTPUT_FILEEXTENSION
FFMPEG_OUTPUT=$(ffmpeg -threads $THREADS -i $OLD_NAME -b:v $OUTPUT_VIDEO_BITRATE -c:v $OUTPUT_VIDEO_FORMAT -r $OUTPUT_VIDEO_FRAMERATE $NEW_NAME 2>&1)
RETURN_VALUE=$? # whether ffmpeg command worked
if [ $RETURN_VALUE -eq 0 ]
then
echo "Successfully converted $OLD_NAME to $NEW_NAME"
else
echo "<!> Failed to convert $OLD_NAME to $NEW_NAME"
fi
LOG_FILE="/tmp/pptx_conv/"$FILE"/$RANDOM"
echo "$FFMPEG_OUTPUT" > "$LOG_FILE"
echo "Saved ffmpeg output to <$LOG_FILE>"
rm $OLD_NAME
done
# change references to video files
for SLIDE in ppt/slides/_rels/*.rels
do
sed -ri 's/Target="..\/media\/(media[0-9]*)\.[^"]*"/Target="..\/media\/\1\.mpg"/g' $SLIDE
done
# Add mime type to [Content_Types].xml
MIME_FILE="[Content_Types].xml"
MIME_LINE="<Default Extension=\"$OUTPUT_FILEEXTENSION\" ContentType=\"video\/$OUTPUT_FILEEXTENSION\"\/>"
PNG_MIME_LINE="<Default Extension=\"png\" ContentType=\"image\/png\"\/>" # add the new mime line behind this
# check whether line is already there
MATCHES=$(cat $MIME_FILE | grep -c $OUTPUT_FILEEXTENSION)
if [ ! $MATCHES -gt 0 ]
then
# no match, so add the line somewhere
sed -i "s/$PNG_MIME_LINE/$PNG_MIME_LINE $MIME_LINE/g" $MIME_FILE
fi
BASE_NAME=$(echo "$FILE" | cut -d "." -f1)
NEW_NAME="$BASE_NAME""_converted.pptx"
echo "Zipping up <$NEW_NAME>..."
zip -r ../"$NEW_NAME" * > /dev/null
# cleanup
cd ..
rm -rf "$FOLDER"
if [ $REMOVE_OLD_FILES -eq 1 ];
then
rm "$FILE"
fi
echo "--------------------"
Leave a Reply