Update: The crash issue appears to be fixed in recent LibreOffice. So there is really no reason to do all of the below any more, hooray. See updated howto.
First, why on earth would you want to do that?
The American Physical Society insists that you upload PPTX slides to their conference server and LibreOffice crashes every time I try to import a movie. The developers on the LO forums say it's not their problem because it works with ODP. Glad you asked.
You'll need pdftoppm (or similar, comes with poppler) and the python-pptx and PIL modules. Also, FFMPEG if your movies still need conversion.
First, create page images, in bash:
pdftoppm mypresentation.pdf img -png -r 250
The output is a series of img-1.png, ...,img-n.png. Resolution is here 250.
If necessary, convert all movies to something PowerPoint will digest. Other containers and codecs might work as well, but my Windows failsafe is WMV2.
ffmpeg -i input.avi -codec:v wmv2 -b:v 2000k output.wmv
Batch conversion:
for m in *.avi; do ffmpeg -i $m -codec:v wmv2 -b:v 2000k ${m%avi}wmv; done
We'll assume that we have movie1.wmv and movie2.wmv on slide 2 and movie3.wmv on slide 5.
Now for the tedious bit - determine the bounding box (left, top, width, height, in px) for each movie on the img-1.png and img-5.png slide images. I just used gwenview's crop tool.
Now for the python script:
from pptx import Presentation
from pptx.util import Inches
from glob import glob
from PIL import Image
prs = Presentation()
prs.slide_width = Inches(16) #assuming 16:9 aspect ratio
prs.slide_height = Inches(9)
blank = prs.slide_layouts[6]
imgs = sorted(glob("img*.png"))
w,h=Image.open(imgs[0]).size
# conversion factor for pixel values to inches.
pxtoin=16./w
slides={}
# did the movie-slide attribution via some kind of messy dictionary/list construction. Use the top,left,width,height values determined above.
movies={4:[['movie3.wmv',[626,323,1263,708]]],
1:[['movie1.wmv',[155,324,710,710]],['movie2.wmv',[1163,324,710,710]]]}
for i in range(len(imgs)):
slides[i] = prs.slides.add_slide(blank)
# add the slide contents as bitmaps
pic = slides[i].shapes.add_picture(imgs[i], 0, 0, height=prs.slide_height)
try:
for it in movies[i]:
movie = slides[i].shapes.add_movie(it[0],*[Inches(r*pxtoin) for r in it[1]])
except KeyError: pass
prs.save("test.pptx")
This got me a minimum working presentation when I tested it on a remote Windows machine, apart from the fact that the movies had ugly speaker icons instead of poster images. There's a poster_frame_image keyword in add_movie where you can provide an image filename, but it didn't seem to change anything.
Sources:
The python-pptx documentation has a lot of basic use cases. https://python-pptx.readthedocs.io/