|
@@ -9,6 +9,7 @@ namespace Publicate.Wizards {
|
|
|
private EntryRow title;
|
|
|
private EntryRow author;
|
|
|
private EntryRow author_email;
|
|
|
+ private ThumbnailChooserRow thumbnail_file;
|
|
|
|
|
|
private ViewerWindow window;
|
|
|
|
|
@@ -31,6 +32,10 @@ namespace Publicate.Wizards {
|
|
|
video_file.title = "Video";
|
|
|
group.add(video_file);
|
|
|
|
|
|
+ thumbnail_file = new ThumbnailChooserRow(window);
|
|
|
+ thumbnail_file.title = "Thumbnail";
|
|
|
+ group.add(thumbnail_file);
|
|
|
+
|
|
|
title = new EntryRow ();
|
|
|
title.title = "Title";
|
|
|
group.add(title);
|
|
@@ -95,12 +100,18 @@ namespace Publicate.Wizards {
|
|
|
var processor = new Video.VideoProcessor();
|
|
|
var result = yield processor.process_video(video_file.selected_file.get_path(), window);
|
|
|
|
|
|
- var builder = new Ppub.Builder();
|
|
|
- builder.add_metadata(metadata);
|
|
|
-
|
|
|
result.manifest.author = metadata.author;
|
|
|
result.manifest.title = metadata.title;
|
|
|
result.manifest.description_file_name = "video_description.md";
|
|
|
+ result.manifest.master = result.video_files.first_or_default()?.get_basename();
|
|
|
+
|
|
|
+ if(thumbnail_file.selected_file != null) {
|
|
|
+ result.manifest.poster = thumbnail_file.selected_file.get_basename();
|
|
|
+ metadata.poster = thumbnail_file.selected_file.get_basename();
|
|
|
+ }
|
|
|
+
|
|
|
+ var builder = new Ppub.Builder();
|
|
|
+ builder.add_metadata(metadata);
|
|
|
|
|
|
var manifest_data = result.manifest.to_string();
|
|
|
print(manifest_data);
|
|
@@ -117,17 +128,14 @@ namespace Publicate.Wizards {
|
|
|
|
|
|
builder.add_asset("video_description.md", "text/markdown", description_stream, Invercargill.empty<string>(), compression_info);
|
|
|
|
|
|
+ if(thumbnail_file.selected_file != null) {
|
|
|
+ yield add_file(builder, thumbnail_file.selected_file);
|
|
|
+ print("Added file\n");
|
|
|
+ }
|
|
|
+
|
|
|
foreach (var result_file in result.video_files) {
|
|
|
- var stream = yield result_file.read_async(Priority.DEFAULT, null);
|
|
|
- var compression = new Ppub.CompressionInfo(stream, false);
|
|
|
- stream.seek(0, SeekType.SET, null);
|
|
|
- var sample = new uint8[2048];
|
|
|
- size_t sample_size;
|
|
|
- yield stream.read_all_async(sample, Priority.DEFAULT, null, out sample_size);
|
|
|
- stream.seek(0, SeekType.SET, null);
|
|
|
-
|
|
|
- var mimetype = Ppub.guess_mimetype(result_file.get_basename(), sample);
|
|
|
- builder.add_asset(result_file.get_basename(), mimetype, stream, Invercargill.empty<string>(), compression);
|
|
|
+ yield add_file(builder, result_file);
|
|
|
+ print("Added video file\n");
|
|
|
}
|
|
|
|
|
|
var output_stream = file.replace(null, false, FileCreateFlags.REPLACE_DESTINATION);
|
|
@@ -146,6 +154,19 @@ namespace Publicate.Wizards {
|
|
|
video_file.reset();
|
|
|
}
|
|
|
|
|
|
+ private static async void add_file(Ppub.Builder builder, File file) throws Error {
|
|
|
+ var stream = yield file.read_async(Priority.DEFAULT, null);
|
|
|
+ var compression = new Ppub.CompressionInfo(stream, false);
|
|
|
+ stream.seek(0, SeekType.SET, null);
|
|
|
+ var sample = new uint8[2048];
|
|
|
+ size_t sample_size;
|
|
|
+ yield stream.read_all_async(sample, Priority.DEFAULT, null, out sample_size);
|
|
|
+ stream.seek(0, SeekType.SET, null);
|
|
|
+
|
|
|
+ var mimetype = Ppub.guess_mimetype(file.get_basename(), sample);
|
|
|
+ builder.add_asset(file.get_basename(), mimetype, stream, Invercargill.empty<string>(), compression);
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private class VideoChooserRow : ActionRow {
|
|
@@ -215,4 +236,59 @@ namespace Publicate.Wizards {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ private class ThumbnailChooserRow : ActionRow {
|
|
|
+
|
|
|
+ private ViewerWindow toplevel;
|
|
|
+
|
|
|
+ public File? selected_file {get; set;}
|
|
|
+
|
|
|
+ public ThumbnailChooserRow(ViewerWindow window) {
|
|
|
+ toplevel = window;
|
|
|
+ reset();
|
|
|
+
|
|
|
+ var button = new Button.from_icon_name("document-open-symbolic");
|
|
|
+ button.clicked.connect(() => open_video.begin());
|
|
|
+ button.margin_bottom = 8;
|
|
|
+ button.margin_top = 8;
|
|
|
+ button.add_css_class("flat");
|
|
|
+ add_suffix(button);
|
|
|
+
|
|
|
+ activatable_widget = button;
|
|
|
+ activatable = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void reset() {
|
|
|
+ selected_file = null;
|
|
|
+ subtitle = "Not selected";
|
|
|
+ }
|
|
|
+
|
|
|
+ public async void open_video() throws Error {
|
|
|
+
|
|
|
+ var dialog = new FileDialog();
|
|
|
+ var filters = new GLib.ListStore(Type.OBJECT);
|
|
|
+ var video_filter = new FileFilter();
|
|
|
+ var all_filter = new FileFilter();
|
|
|
+ filters.append(video_filter);
|
|
|
+ filters.append(all_filter);
|
|
|
+ video_filter.add_mime_type("image/jpeg");
|
|
|
+ video_filter.add_mime_type("image/png");
|
|
|
+ video_filter.name = "Image Files";
|
|
|
+ all_filter.add_pattern("*");
|
|
|
+ all_filter.name = "All Files";
|
|
|
+
|
|
|
+ dialog.filters = filters;
|
|
|
+ dialog.set_initial_file(selected_file);
|
|
|
+ var file = yield dialog.open(toplevel, null);
|
|
|
+
|
|
|
+ if(file == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ selected_file = file;
|
|
|
+ subtitle = selected_file.get_basename();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|