Processing PDF files: Auto advance
2010-02-23 22:35
Sometimes you need a PDF file that auto advances (auto flip, slide show) pages after a certain amount of seconds. For example for presenting a Lightning Talk the Ingnite way. There are several ways to achieve this. Today I've spent hours to find the best way.
You could just hope that your favourite PDF viewer supports changing slides automatically in a certain interval (Evince doesn't). But you never know which viewer will be used when you rely on other people's computers. The next step is obvious, try to get the PDF file itself to auto advance. It is possible as Adobe Acrobat supports such a setting (it seems that even Acrobat Reader does, though I can't find that option in my one under Linux), I just need to find out how.
After some further research I found out that Latex' hyperref package
supports it as well (no, I don't speak Czech). So I made some minimal
Latex Beamer presentation to
give it a try. The important notice that the \hypersetup{pdfpageduration=n}
must be the first item within a \begin{frame}
was found
in
some presentation guidelines. Guess what? It even works with Evince (tex file, PDF file).
I'm getting closer. Though my problem is that I create my slides with
Inkscape (resp. Inkscape Slide), so I
can't really user Latex Beamer for it. But the previously mentioned
presentation guidelines also mention the /Dur
entry in the PDF
page object. So it should be easy to add it manually. And it really is. A quick
search through the PDF file generated by Latex you can see that
/Dur
occurs a close to /MediaBox
. After adding those
/Dur 2
to my original presentation PDF file right after
\MediaBox
it auto flipped every 2 seconds.
I could have written a simple script that adds it to the PDF at the right place, but that sounds pretty fragile. A better approach would be to use a PDF library that is meant for manipulating PDF files. As my favourite programming language is Python at the moment, I came across pyPdf. A quick look at the internals showed that it contains everything I need.
Here's my final solution for the problem of creating auto advancing PDF slides. A small script that does exactly what I need (and not more). I've used the Python 3 version of pyPdf, but the script should look similar for Python 2.x.
#!/usr/bin/env python3.1
# Copyright (c) 2010 Volker Mische (http://vmx.cx/)
# Licensed under MIT.
import sys
from pyPdf import PdfFileWriter, PdfFileReader
from pyPdf.generic import NameObject, NumberObject
def main(argv=None):
if argv is None:
argv = sys.argv
if len(argv) != 4:
print('Usage: setduration.py [duration-in-seconds] [input-pdf]',
'[output-pdf]')
return
pdfin = PdfFileReader(open(argv[2], "rb"))
pdfout = PdfFileWriter()
for page in pdfin.pages:
page[NameObject('/Dur')] = NumberObject(argv[1])
pdfout.addPage(page)
outputStream = open(argv[3], "wb")
pdfout.write(outputStream)
if __name__ == '__main__':
sys.exit(main())