Usage
-----
-Run "webdvd URL DIR" where URL is the URL for the page that is to be
-the top menu of the DVD and DIR is the directory in which to create
-the DVD filesystem (which should be missing or empty). It will
-automatically follow links to other pages and to video files,
-rendering each page. You must be careful not to link to pages that
-you do not want to appear on the disc, such as normal web sites.
+Design your DVD menus as a series of HTML pages linking to each other
+and to MPEG-1/2 videos that are suitable for use on a DVD. Currently
+the videos must be local files with filenames ending in ".vob", but no
+such restrictions apply to the HTML pages. You must be careful not to
+link to pages that you do not want to appear on the disc, such as
+normal web sites. Also note the limitations listed below.
By default, webdvd generates PAL/SECAM video. If you wish to produce
-NTSC DVDs you can override this by adding the option "--video-std ntsc".
+NTSC DVDs you can override this by adding the option "--video-std ntsc"
+to the following commands.
-If webdvd runs successfully you can use mkisofs to create a DVD image:
+To get a rough preview of the menus, run "webdvd --preview menu-url"
+where menu-url is the URL of the first page to show. Currently
+videos cannot be displayed in this preview mode; if you select one it
+will cause WebDVD to exit.
+
+To create a DVD filesystem, run "webdvd menu-url output-dir" where
+menu-url is the address of the top menu page and output-dir is the
+directory in which to create the filesystem (which should be either
+nonexistent or empty). WebDVD will automatically follow links to the
+other pages and to the video files.
+
+If this is successful you can then use mkisofs to create a DVD image:
mkisofs -dvd-video DIR > IMAGE
rm -rf DIR
Alternately you can write the filesystem directly to a writable DVD
-with growisofs or mkisofs plus a suitable version of cdrecord.
+with growisofs or with mkisofs piped to a suitable version of
+cdrecord.
Limitations
-----------
a stylesheet to all pages that adds 50-60 pixels of padding on all
sides of the body.
+DVD players do not have "back" buttons, so you should generally
+provide links to "higher" menu pages. However, they do have a button
+for returning to the top menu.
+
WebDVD sends a "mouseover" event for each link and sets it into its
"hover" state, then records how this changes its appearance. This
change is then shown when the corresponding button on the DVD menu is
check(browser->GetContentDOMWindow(
getter_AddRefs(dom_window)));
- if (!link_state_.get())
+ if (output_dir_.empty())
{
apply_style_sheet(stylesheet_, pres_shell);
- save_screenshot();
}
- process_links(pres_shell, pres_context, dom_window);
- if (!link_state_.get())
+ else
{
- page_queue_.pop();
- if (page_queue_.empty())
+ if (!link_state_.get())
+ {
+ apply_style_sheet(stylesheet_, pres_shell);
+ save_screenshot();
+ }
+
+ process_links(pres_shell, pres_context, dom_window);
+
+ if (!link_state_.get())
{
- generate_dvd();
- Gtk::Main::quit();
+ page_queue_.pop();
+ if (page_queue_.empty())
+ {
+ generate_dvd();
+ Gtk::Main::quit();
+ }
+ else
+ {
+ load_next_page();
+ }
}
- else
- load_next_page();
}
}
catch (std::exception & e)
{
stream << "Usage: " << command_name
<< (" [gtk-options] [--video-std std-name]"
- " front-page-url output-dir\n");
+ " [--preview] menu-url [output-dir]\n");
}
} // namespace
{
try
{
- // Do initial argument parsing. We have to do this before
- // letting Gtk parse the arguments since we need to spawn Xvfb
- // first and that's currently dependent on the frame
- // parameters (though we could just make it large enough for
- // any frame) and also an unnecessary expense in some cases.
video::frame_params frame_params = video::pal_params;
- for (int argi = 1; argi != argc; ++argi)
+ bool preview_mode = false;
+
+ // Do initial argument parsing. We have to do this before
+ // letting Gtk parse the arguments since we may need to spawn
+ // Xvfb first.
+ int argi = 1;
+ while (argi != argc)
{
if (std::strcmp(argv[argi], "--") == 0)
+ {
break;
- if (std::strcmp(argv[argi], "--help") == 0)
+ }
+ else if (std::strcmp(argv[argi], "--help") == 0)
{
print_usage(std::cout, argv[0]);
return EXIT_SUCCESS;
}
- if (std::strcmp(argv[argi], "--video-std") == 0)
+ else if (std::strcmp(argv[argi], "--preview") == 0)
+ {
+ preview_mode = true;
+ argi += 1;
+ }
+ else if (std::strcmp(argv[argi], "--video-std") == 0)
{
if (argi + 1 == argc)
{
return EXIT_FAILURE;
}
frame_params = lookup_frame_params(argv[argi + 1]);
- break;
+ argi += 2;
+ }
+ else
+ {
+ argi += 1;
}
}
-
- // Spawn Xvfb and set env variables so that Xlib will use it
- // Use 8 bits each for RGB components, which should translate into
- // "enough" bits for YUV components.
- FrameBuffer fb(frame_params.width, frame_params.height, 3 * 8);
- setenv("XAUTHORITY", fb.get_x_authority().c_str(), true);
- setenv("DISPLAY", fb.get_x_display().c_str(), true);
+
+ std::auto_ptr<FrameBuffer> fb;
+ if (!preview_mode)
+ {
+ // Spawn Xvfb and set env variables so that Xlib will use it
+ // Use 8 bits each for RGB components, which should translate into
+ // "enough" bits for YUV components.
+ fb.reset(new FrameBuffer(frame_params.width, frame_params.height,
+ 3 * 8));
+ setenv("XAUTHORITY", fb->get_x_authority().c_str(), true);
+ setenv("DISPLAY", fb->get_x_display().c_str(), true);
+ }
// Initialise Gtk
Gtk::Main kit(argc, argv);
// Complete argument parsing with Gtk's options out of the way.
- int argi = 1;
+ argi = 1;
while (argi != argc)
{
- if (std::strcmp(argv[argi], "--video-std") == 0)
+ if (std::strcmp(argv[argi], "--") == 0)
{
- argi += 2;
+ argi += 1;
+ break;
}
- else if (std::strcmp(argv[argi], "--") == 0)
+ else if (std::strcmp(argv[argi], "--preview") == 0)
{
argi += 1;
- break;
+ }
+ else if (std::strcmp(argv[argi], "--video-std") == 0)
+ {
+ argi += 2;
}
else if (argv[argi][0] == '-')
{
return EXIT_FAILURE;
}
else
+ {
break;
+ }
}
- if (argi != argc - 2)
+ if (argc - argi != (preview_mode ? 1 : 2))
{
print_usage(std::cerr, argv[0]);
return EXIT_FAILURE;
// Initialise Mozilla
BrowserWidget::init();
- WebDvdWindow window(frame_params, argv[argi], argv[argi + 1]);
+ WebDvdWindow window(frame_params,
+ argv[argi],
+ preview_mode ? "" : argv[argi + 1]);
Gtk::Main::run(window);
}
catch (std::exception & e)