vmx

the blllog.

2010-02-23 22:27

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()) 

Categories: en, Python