Oggscissors is a command line utility to cut and join Ogg Vorbis logical streams without reencoding. Cutting is similar to vcut from vorbis-tools package, but this utility goes further. Pages are recreated and granulepos values are recomputed to start from zero. Cut times are specified in seconds. Oggscissors allow to cut with roughly 20 ms precision. (Smallest unit of Vorbis stream is one packet, which is typically 1024 samples. That equals to 20 ms in 48000 Hz audio stream.)

Joining is as far as I know, unique ability of this tool. Joining is not being done as chaining of several logical streams. Instead, packets from two separate logical streams are copied into single logical stream, pages are regenerated and granulepos values are recomputed.

Oggscissors can be also used to normalize granulepos values on a partial internet stream recording.

There's also an analyze mode, which dumps details about inner structure of Ogg Vorbis stream, namely pages, packets, and all important values of these.


Oggscissors is a Python script. It makes use of pyogg and pyvorbis libraries. Sadly pyogg-1.3 does not allow to manipulate BOS/EOS flags on packets from Python interface. You must apply this patch to your pyogg, otherwise Oggscissors will not work properly. As pyogg looks unmaintained, I haven't submitted this patch upstream. If you're using FreeBSD, the patch fits nicely into the pyogg port. Just put it into audio/py-ogg/files and name it patch-flags or similar.




2007-01-27 Revision 3: fix runtime on recent Python. Submitted by Eike von Seggern, thanks!

2005-01-09 Revision 2: fix handling of files with hole in data, typically partial recording of live streams. Also read sample rate from the file, instead of hardcoding 48000.

2005-01-04 Revision 1: first public version.


oggscissors.py --from=POS1 --upto=POS2 source.ogg output.ogg

Cut the section of source.ogg starting at time POS1 in seconds, ending at time POS2 in seconds. Both --from and --upto can be ommitted, cutting is done from the beginning or to the end of the file, respectively. Both arguments can be ommitted at the same time, leading to full copy of source file with recomputed timings. Script accept fractions of seconds, things like --from=68.7 works as expected.

oggscissors.py --join source1.ogg source2.ogg output.ogg

Join two files into single logical stream.

oggscissors.py --analyze source.ogg

Prints details on pages and packets in ogg file, as provided by pyogg library.

Known Bugs

Timing recomputation code is doing assumptions from time to time, but I see no way how to fix that, other than actually decoding all packets and counting samples in them.

There is no documentation except this webpage, and there are no comments in the source.


Pav Lucistnik <pav@FreeBSD.org>

Based on examples from pyogg package.


My BSD place - My website