Pārlūkot izejas kodu

Better video support

Billy Barrow 2 gadi atpakaļ
vecāks
revīzija
5b3b77f2ad

+ 11 - 0
src/DocumentView/DocumentViewManager.vala

@@ -50,6 +50,8 @@ namespace PpubViewer.DocumentView {
 
         public void set_zoom_percentage(int percent) {
             markdown_view.set_zoom_percentage(percent);
+            text_view.set_zoom_percentage(percent);
+            video_view.set_zoom_percentage(percent);
         }
 
         public void set_scroll_position(double position) {
@@ -81,6 +83,14 @@ namespace PpubViewer.DocumentView {
             text_view.visible = false;
             unsupported_view.visible = false;
             video_view.visible = false;
+            video_view.reset();
+        }
+
+        public override void reflow() {
+            markdown_view.reflow();
+            text_view.reflow();
+            unsupported_view.reflow();
+            video_view.reflow();
         }
 
         private void set_view(DocumentViewWidget view) {
@@ -96,6 +106,7 @@ namespace PpubViewer.DocumentView {
         public abstract void set_zoom_percentage(int percent);
         public abstract void set_scroll_position(double position);
         public abstract void load_asset(Ppub.Publication publication, Ppub.Asset asset);
+        public virtual void reflow() {}
         public signal void link_clicked(string href);
     }
 

+ 2 - 2
src/DocumentView/MarkdownView.vala

@@ -7,14 +7,14 @@ namespace PpubViewer.DocumentView {
     public class MarkdownView : Box, DocumentViewWidget {
 
         protected ScrolledWindow scrolled_window;
-        protected ClampScrollable clamp;
+        protected Clamp clamp;
         protected GtkCommonMark.MarkdownView markdown_view;
         private Ppub.Publication publication;
 
         public MarkdownView() {
             orientation = Orientation.VERTICAL;
             scrolled_window = new ScrolledWindow ();
-            clamp = new ClampScrollable ();
+            clamp = new Clamp ();
             clamp.maximum_size = 800;
             scrolled_window.child = clamp;
             scrolled_window.set_policy (PolicyType.NEVER, PolicyType.AUTOMATIC);

+ 9 - 2
src/DocumentView/PlainTextView.vala

@@ -10,6 +10,8 @@ namespace PpubViewer.DocumentView {
         private ClampScrollable clamp;
         private TextView text_view;
 
+        private TextTag tag;
+
         public PlainTextView() {
             orientation = Orientation.VERTICAL;
             scrolled_window = new ScrolledWindow ();
@@ -20,6 +22,7 @@ namespace PpubViewer.DocumentView {
             scrolled_window.vexpand = true;
 
             text_view = new TextView ();
+            tag = text_view.buffer.create_tag (null);
             text_view.editable = false;
             text_view.monospace = true;
             text_view.set_wrap_mode (WrapMode.WORD_CHAR);
@@ -38,7 +41,7 @@ namespace PpubViewer.DocumentView {
 
         public void set_zoom_percentage (int percent) {
             var scale = (float)percent / 100f;
-            // TODO
+            tag.size_points = scale * 12;
         }
 
         public void set_scroll_position (double position) {
@@ -46,11 +49,15 @@ namespace PpubViewer.DocumentView {
         }
         
         public void load_asset (Ppub.Publication publication, Ppub.Asset asset) {
+            text_view.buffer.set_text("", 0);
             MemoryOutputStream os = new MemoryOutputStream (null, GLib.realloc, GLib.free);
             os.splice (publication.read_asset (asset.name), OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET);
             var text = os.steal_data ();
             text.length = (int) os.get_data_size ();
-            text_view.buffer.set_text((string)text, text.length);
+
+            Gtk.TextIter iter;
+            text_view.buffer.get_start_iter (out iter);
+            text_view.buffer.insert_with_tags (ref iter, (string)text, text.length, tag);
         }
 
     }

+ 82 - 14
src/DocumentView/VideoView.vala

@@ -4,43 +4,111 @@ using GtkCommonMark;
 
 namespace PpubViewer.DocumentView {
 
-    public class VideoView : MarkdownView {
+    public class VideoView : MarkdownView, DocumentViewWidget {
 
         private Box box;
         private Ppub.VideoManifest ppvm;
+        private Stack video_stack;
+        private Clamp video_clamp;
+        private Spinner spinner;
         private Video video;
-        private MediaStream current_stream;
+        private Ppub.Publication publication;
+
+        private File temp = null;
+        private double ratio_frac = 1;
+
 
         public VideoView() {
             base();
 
-            box = new Box(Orientation.VERTICAL, 8);
+            box = new Box(Orientation.VERTICAL, 0);
             scrolled_window.child = box;
             markdown_view.vexpand = true;
             
             video = new Video();
-            box.append (video);
-            box.append (clamp);
+            video_stack = new Stack();
+            video_clamp = new Clamp ();
+            spinner = new Spinner();
+            
+            spinner.halign = Align.CENTER;
+            spinner.valign = Align.CENTER;
+            video_clamp.maximum_size = 1280;
+            video_clamp.child = video_stack;
+            spinner.spinning = true;
+            video_stack.add_child (spinner);
+            video_stack.add_child (video);
+            video_stack.transition_type = StackTransitionType.CROSSFADE;
+            video_stack.visible_child = spinner;
+            video_stack.vhomogeneous = true;
 
+            box.append (video_clamp);
+            box.append (clamp);
         }
 
         public override void load_asset (Ppub.Publication publication, Ppub.Asset asset) {
+            this.publication = publication;
+            video_stack.visible_child = spinner;
 
             var stream = publication.read_asset (asset.name);
             ppvm = new Ppub.VideoManifest.from_stream (stream);
-
-            var s = publication.read_asset(ppvm.streams.first().file_name);
-            var tmp = File.new_for_path ("/tmp/video");
-            var ts = tmp.create (FileCreateFlags.REPLACE_DESTINATION);
-            ts.splice (s, OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET);
-
-            var mf = MediaFile.for_file (tmp);
-            video.set_media_stream(mf);
         
-            print(@"Error: $(mf.error?.message)\n");
+            ratio_frac = ppvm.ratio[1] / ppvm.ratio[0];
             
             var description_asset = publication.get_asset (ppvm.description_file_name);
             base.load_asset (publication, description_asset);
+
+            new Thread<void>("ppvm_video_extractor", () => prepare_stream(ppvm.streams.first()));
+        }
+
+        private void prepare_stream(Ppub.VideoDescription video) throws Error {
+
+            cleanup();
+
+            var s = publication.read_asset(ppvm.streams.first().file_name);
+            FileIOStream fios;
+            temp = File.new_tmp("ppub_ppvm_tmp_video_XXXXXX", out fios);
+
+            fios.output_stream.splice(s, OutputStreamSpliceFlags.CLOSE_SOURCE | OutputStreamSpliceFlags.CLOSE_TARGET);
+
+            GLib.Idle.add(video_ready);
+
+        }
+
+        private bool video_ready() {
+
+            var mf = MediaFile.for_file (temp);
+            video.set_media_stream(mf);
+            video_stack.visible_child = video;
+
+            return false;
+        }
+
+
+        public override void reflow() {
+            var video_height = video_stack.get_width () * ratio_frac;
+            video_stack.height_request = (int)video_height;
+        }
+
+        public void reset() {
+            video.set_media_stream(null);
+            video_stack.visible_child = spinner;
+            cleanup();
+        }
+
+        private void cleanup() {
+            if(temp != null) {
+                try{
+                    temp.delete();
+                }
+                catch {
+                    warning(@"Could not clean up temporary file \"$(temp.get_path())\".");
+                }
+                temp = null;
+            }
+        }
+
+        ~VideoView() {
+            cleanup();
         }
 
     }

+ 5 - 0
src/Window.vala

@@ -206,6 +206,11 @@ namespace PpubViewer {
             document_view.set_zoom_percentage(percent);
         }
 
+        public override void size_allocate(int width, int height, int baseline) {
+            base.size_allocate(width, height, baseline);
+            document_view.reflow();
+        }
+
     }
 
 }