Skip to content

Commit

Permalink
Movie: Add playback of attached movies
Browse files Browse the repository at this point in the history
Such movies may be added in LaTeX with the movie15 package.

This requires Poppler.AnnotFileAttachment.  Vala 0.14 (and earlier,
presumably) don't have this in the .vapi files, so we add it by hand.
Vala 0.16 should be converted to .gir files and won't need this.
  • Loading branch information
rschroll committed Aug 10, 2012
1 parent da9ffa1 commit f550a8b
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -63,6 +63,10 @@ link_directories(${LIB_PATHS})
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/paths.in ${CMAKE_CURRENT_SOURCE_DIR}/paths.vala)

file (GLOB_RECURSE VALA_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala)
# Vala 0.14 (and presumably lower) doesn't have Poppler.AnnotFileAttachment
if(${VALA_VERSION} VERSION_LESS "0.16.0")
set(VALA_SRC ${VALA_SRC} poppler-annot-file-attachment.vapi)
endif(${VALA_VERSION} VERSION_LESS "0.16.0")

vala_precompile(VALA_C
${VALA_SRC}
Expand Down
70 changes: 65 additions & 5 deletions src/classes/action/movie.vala
Expand Up @@ -10,14 +10,16 @@ namespace pdfpc {
public dynamic Element pipeline;
protected bool eos = false;
protected bool loop;
protected string temp;

public Movie(Poppler.Rectangle area,
PresentationController controller, Poppler.Document document,
string file, bool autostart, bool loop) {
string uri, bool autostart, bool loop, bool temp=false) {
base(area, controller, document);
this.loop = loop;
this.temp = temp ? uri.substring(7) : "";
GLib.Idle.add( () => {
this.establish_pipeline(file);
this.establish_pipeline(uri);
if (autostart)
this.play();
return false;
Expand Down Expand Up @@ -61,12 +63,58 @@ namespace pdfpc {
}
bool uncertain;
var ctype = GLib.ContentType.guess(uri, null, out uncertain);
if (ctype.split("/", 2)[0] == "video")
if ("video" in ctype)
return true;
}
return false;
}

public override ActionMapping? new_from_annot_mapping(Poppler.AnnotMapping mapping,
PresentationController controller, Poppler.Document document) {
string uri;
bool autostart, loop, temp;
if (Movie.parse_annot_mapping(mapping, controller, out uri, out autostart, out loop, out temp))
return new Movie(mapping.area, controller, document, uri, autostart, loop, temp) as ActionMapping;
return null;
}

public static bool parse_annot_mapping(Poppler.AnnotMapping mapping, PresentationController controller, out string uri, out bool autostart, out bool loop, out bool temp) {
var annot = mapping.annot;
if (annot.get_annot_type() == Poppler.AnnotType.FILE_ATTACHMENT) {
var attach = ((Poppler.AnnotFileAttachment)annot).get_attachment();
if (!("video" in attach.description))
return false;

string tmp_fn;
int fh;
try {
fh = FileUtils.open_tmp(null, out tmp_fn);
} catch (FileError e) {
warning("Could not create temp file: %s", e.message);
return false;
}
FileUtils.close(fh);
try {
attach.save(tmp_fn);
} catch (Error e) {
warning("Could not save temp file: %s", e.message);
return false;
}
stdout.printf(@"Temp file $tmp_fn\n");
uri = "file://" + tmp_fn;
autostart = false;
loop = false;
temp = true;
return true;
//g_free(&attach);
}
/*if (mapping.annot.get_annot_type() == Poppler.AnnotType.SCREEN) {
stdout.printf("Parsing annot mapping -- Screen\n");
stdout.printf(@"$(annot.get_contents())\n");
}*/
return false;
}

protected void establish_pipeline(string uri) {
var bin = new Bin("bin");
var tee = ElementFactory.make("tee", "tee");
Expand Down Expand Up @@ -156,6 +204,9 @@ namespace pdfpc {

public override void deactivate() {
this.stop();
if (this.temp != "")
if (FileUtils.unlink(this.temp) != 0)
warning("Problem deleting temp file %s", this.temp);
}
}

Expand All @@ -175,8 +226,8 @@ namespace pdfpc {
protected bool drag_was_playing;

public ControlledMovie(Poppler.Rectangle area,
PresentationController controller, Poppler.Document document, string file, bool autostart, bool loop) {
base(area, controller, document, file, autostart, loop);
PresentationController controller, Poppler.Document document, string file, bool autostart, bool loop, bool temp=false) {
base(area, controller, document, file, autostart, loop, temp);
controller.main_view.motion_notify_event.connect(this.on_motion);
controller.main_view.button_release_event.connect(this.on_button_release);
}
Expand All @@ -194,6 +245,15 @@ namespace pdfpc {
return null;
}

public override ActionMapping? new_from_annot_mapping(Poppler.AnnotMapping mapping,
PresentationController controller, Poppler.Document document) {
string uri;
bool autostart, loop, temp;
if (Movie.parse_annot_mapping(mapping, controller, out uri, out autostart, out loop, out temp))
return new ControlledMovie(mapping.area, controller, document, uri, autostart, loop, temp) as ActionMapping;
return null;
}

protected override Element link_additional(int n, Element source, Bin bin,
Gdk.Rectangle rect) {
if (n != 0)
Expand Down
2 changes: 2 additions & 0 deletions src/classes/metadata/pdf.vala
Expand Up @@ -194,6 +194,8 @@ namespace pdfpc.Metadata {
*/
public void quit() {
this.save_to_disk();
foreach (var mapping in this.action_mapping)
mapping.deactivate();
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/poppler-annot-file-attachment.vapi
@@ -0,0 +1,9 @@
namespace Poppler {
[CCode (cheader_filename = "poppler.h")]
public class AnnotFileAttachment : Poppler.AnnotMarkup {
[CCode (has_construct_function = false)]
protected AnnotFileAttachment ();
public unowned Poppler.Attachment get_attachment ();
public unowned string get_name ();
}
}

0 comments on commit f550a8b

Please sign in to comment.