2013-03-12 17:00:09 -04:00
/*
2019-08-02 17:26:43 -04:00
* Copyright ( C ) 2013 - 2015 John Emmas < john @ creativepost . co . uk >
* Copyright ( C ) 2013 - 2018 Paul Davis < paul @ linuxaudiosystems . com >
2022-04-14 19:53:55 -04:00
* Copyright ( C ) 2013 - 2022 Robin Gareus < robin @ gareus . org >
2019-08-02 17:26:43 -04:00
* Copyright ( C ) 2015 André Nusser < andre . nusser @ googlemail . com >
* Copyright ( C ) 2016 Tim Mayberry < mojofunk @ gmail . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along
* with this program ; if not , write to the Free Software Foundation , Inc . ,
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
*/
2013-03-12 17:00:09 -04:00
# include <cstdio>
# include <iomanip>
2022-02-07 16:46:23 -05:00
# include <sstream>
# include <string>
2013-03-12 17:00:09 -04:00
# include <sigc++/bind.h>
2017-07-16 21:48:18 -04:00
# include <gtkmm/filechooserdialog.h>
2022-02-07 16:46:23 -05:00
# include <gtkmm/frame.h>
2017-07-16 21:48:18 -04:00
# include <gtkmm/stock.h>
# include <gtkmm/table.h>
2013-03-12 17:00:09 -04:00
# include "pbd/convert.h"
2022-02-07 16:46:23 -05:00
# include "pbd/error.h"
2013-03-12 17:00:09 -04:00
# include "ardour/session.h"
2022-02-07 16:46:23 -05:00
# include "ardour/session_directory.h"
2013-03-12 17:00:09 -04:00
# include "ardour_ui.h"
# include "gui_thread.h"
# include "ardour/export_channel_configuration.h"
# include "ardour/export_filename.h"
2022-02-07 16:46:23 -05:00
# include "ardour/export_format_specification.h"
# include "ardour/export_handler.h"
# include "ardour/export_timespan.h"
2013-03-12 17:00:09 -04:00
# include "ardour/session_metadata.h"
2022-04-14 19:53:55 -04:00
# include "gtkmm2ext/utils.h"
2022-04-15 12:25:18 -04:00
# include "widgets/tooltips.h"
2022-04-14 19:53:55 -04:00
2022-02-07 16:46:23 -05:00
# include "ardour_message.h"
2013-03-12 17:00:09 -04:00
# include "export_video_dialog.h"
# include "utils_videotl.h"
2022-02-07 16:46:23 -05:00
2016-07-14 14:44:52 -04:00
# include "pbd/i18n.h"
2013-03-12 17:00:09 -04:00
using namespace Gtk ;
using namespace std ;
using namespace PBD ;
using namespace ARDOUR ;
2022-04-15 12:25:18 -04:00
using namespace ArdourWidgets ;
2013-08-03 10:54:57 -04:00
using namespace VideoUtils ;
2013-03-12 17:00:09 -04:00
2015-02-27 17:17:26 -05:00
ExportVideoDialog : : ExportVideoDialog ( )
2013-03-12 17:00:09 -04:00
: ArdourDialog ( _ ( " Export Video File " ) )
2022-02-07 16:46:23 -05:00
, _aborted ( false )
, _normalize ( false )
, _previous_progress ( 0 )
, _transcoder ( 0 )
2022-01-26 16:19:32 -05:00
, outfn_path_label ( _ ( " File: " ) , Gtk : : ALIGN_START )
2013-03-12 17:00:09 -04:00
, outfn_browse_button ( _ ( " Browse " ) )
2022-01-26 16:19:32 -05:00
, invid_path_label ( _ ( " Video: " ) , Gtk : : ALIGN_START )
2013-03-12 17:00:09 -04:00
, invid_browse_button ( _ ( " Browse " ) )
, transcode_button ( _ ( " Export " ) )
, abort_button ( _ ( " Abort " ) )
2015-03-24 22:39:47 -04:00
, progress_box ( 0 )
2022-04-15 12:25:18 -04:00
, normalize_checkbox ( _ ( " Normalize audio " ) )
, copy_video_codec_checkbox ( _ ( " Mux only - copy video codec " ) )
, meta_checkbox ( _ ( " Include session metadata " ) )
2013-07-23 14:24:23 -04:00
, debug_checkbox ( _ ( " Debug Mode: Print ffmpeg command and output to stdout. " ) )
2013-03-12 17:00:09 -04:00
{
set_name ( " ExportVideoDialog " ) ;
set_modal ( true ) ;
set_skip_taskbar_hint ( true ) ;
set_resizable ( false ) ;
Gtk : : Label * l ;
vbox = manage ( new VBox ) ;
HBox * path_hbox ;
2013-03-27 11:04:56 -04:00
/* check if ffmpeg can be found */
2022-02-07 16:46:23 -05:00
_transcoder = new TranscodeFfmpeg ( X_ ( " " ) ) ;
if ( ! _transcoder - > ffexec_ok ( ) ) {
2022-01-26 16:19:32 -05:00
l = manage ( new Label ( _ ( " ffmpeg installation was not found. Video Export is not possible. See the Log window for more information. " ) , Gtk : : ALIGN_START , Gtk : : ALIGN_CENTER , false ) ) ;
2022-02-07 16:46:23 -05:00
l - > set_line_wrap ( ) ;
2013-03-27 11:04:56 -04:00
vbox - > pack_start ( * l , false , false , 8 ) ;
2022-02-07 16:46:23 -05:00
get_vbox ( ) - > pack_start ( * vbox , false , false ) ;
2013-03-27 11:04:56 -04:00
add_button ( Stock : : OK , RESPONSE_CANCEL ) ;
show_all_children ( ) ;
2022-02-07 16:46:23 -05:00
delete _transcoder ;
_transcoder = 0 ;
2013-03-27 11:04:56 -04:00
return ;
}
2022-02-07 16:46:23 -05:00
delete _transcoder ;
_transcoder = 0 ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
Gtk : : Frame * f ;
2022-04-14 19:53:55 -04:00
Table * t ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
f = manage ( new Gtk : : Frame ( _ ( " Output (file extension defines format) " ) ) ) ;
2013-03-12 17:00:09 -04:00
path_hbox = manage ( new HBox ) ;
path_hbox - > pack_start ( outfn_path_label , false , false , 3 ) ;
path_hbox - > pack_start ( outfn_path_entry , true , true , 3 ) ;
path_hbox - > pack_start ( outfn_browse_button , false , false , 3 ) ;
2022-02-07 16:46:23 -05:00
f - > add ( * path_hbox ) ;
path_hbox - > set_border_width ( 2 ) ;
vbox - > pack_start ( * f , false , false , 4 ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
f = manage ( new Gtk : : Frame ( _ ( " Input " ) ) ) ;
VBox * input_box = manage ( new VBox ) ;
path_hbox = manage ( new HBox ) ;
2013-03-12 17:00:09 -04:00
path_hbox - > pack_start ( invid_path_label , false , false , 3 ) ;
path_hbox - > pack_start ( invid_path_entry , true , true , 3 ) ;
path_hbox - > pack_start ( invid_browse_button , false , false , 3 ) ;
2022-02-07 16:46:23 -05:00
input_box - > pack_start ( * path_hbox , false , false , 2 ) ;
2013-03-12 17:00:09 -04:00
path_hbox = manage ( new HBox ) ;
2022-01-26 16:19:32 -05:00
l = manage ( new Label ( _ ( " Audio: " ) , ALIGN_START , ALIGN_CENTER , false ) ) ;
2013-04-02 18:58:19 -04:00
path_hbox - > pack_start ( * l , false , false , 3 ) ;
2022-01-26 16:19:32 -05:00
l = manage ( new Label ( _ ( " Master Bus " ) , ALIGN_START , ALIGN_CENTER , false ) ) ;
2013-04-02 18:58:19 -04:00
path_hbox - > pack_start ( * l , false , false , 2 ) ;
2022-02-07 16:46:23 -05:00
input_box - > pack_start ( * path_hbox , false , false , 2 ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
input_box - > set_border_width ( 2 ) ;
f - > add ( * input_box ) ;
vbox - > pack_start ( * f , false , false , 4 ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
outfn_path_entry . set_width_chars ( 38 ) ;
2013-03-12 17:00:09 -04:00
2022-04-14 19:53:55 -04:00
audio_bitrate_combo . append ( _ ( " (default for codec) " ) ) ;
audio_bitrate_combo . append ( " 64k " ) ;
audio_bitrate_combo . append ( " 128k " ) ;
audio_bitrate_combo . append ( " 192k " ) ;
audio_bitrate_combo . append ( " 256k " ) ;
audio_bitrate_combo . append ( " 320k " ) ;
2022-11-10 19:53:19 -05:00
audio_sample_rate_combo . append ( _ ( " Session Rate " ) ) ;
2022-04-14 19:53:55 -04:00
audio_sample_rate_combo . append ( " 44100 " ) ;
audio_sample_rate_combo . append ( " 48000 " ) ;
2022-02-07 16:46:23 -05:00
f = manage ( new Gtk : : Frame ( _ ( " Settings " ) ) ) ;
t = manage ( new Table ( 3 , 2 ) ) ;
t - > set_border_width ( 2 ) ;
2013-03-12 17:00:09 -04:00
t - > set_spacings ( 4 ) ;
2013-04-02 18:58:19 -04:00
int ty = 0 ;
2022-04-14 19:53:55 -04:00
l = manage ( new Label ( _ ( " Range: " ) , ALIGN_START , ALIGN_CENTER , false ) ) ;
2022-02-07 16:46:23 -05:00
t - > attach ( * l , 0 , 1 , ty , ty + 1 ) ;
t - > attach ( insnd_combo , 1 , 2 , ty , ty + 1 ) ;
ty + + ;
2022-11-10 19:53:19 -05:00
l = manage ( new Label ( _ ( " Sample Rate: " ) , ALIGN_START , ALIGN_CENTER , false ) ) ;
2022-04-14 19:53:55 -04:00
t - > attach ( * l , 0 , 1 , ty , ty + 1 ) ;
t - > attach ( audio_sample_rate_combo , 1 , 2 , ty , ty + 1 ) ;
ty + + ;
l = manage ( new Label ( _ ( " Audio Quality: " ) , ALIGN_START , ALIGN_CENTER , false ) ) ;
t - > attach ( * l , 0 , 1 , ty , ty + 1 ) ;
t - > attach ( audio_bitrate_combo , 1 , 2 , ty , ty + 1 ) ;
ty + + ;
2022-02-07 16:46:23 -05:00
t - > attach ( normalize_checkbox , 0 , 2 , ty , ty + 1 ) ;
ty + + ;
2022-04-14 19:53:55 -04:00
t - > attach ( copy_video_codec_checkbox , 0 , 2 , ty , ty + 1 ) ;
ty + + ;
2022-02-07 16:46:23 -05:00
t - > attach ( meta_checkbox , 0 , 2 , ty , ty + 1 ) ;
ty + + ;
t - > attach ( debug_checkbox , 0 , 2 , ty , ty + 1 ) ;
ty + + ;
f - > add ( * t ) ;
vbox - > pack_start ( * f , false , true , 4 ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
get_vbox ( ) - > set_spacing ( 4 ) ;
get_vbox ( ) - > pack_start ( * vbox , false , false ) ;
2013-03-12 17:00:09 -04:00
progress_box = manage ( new VBox ) ;
progress_box - > pack_start ( pbar , false , false ) ;
progress_box - > pack_start ( abort_button , false , false ) ;
2022-02-07 16:46:23 -05:00
get_vbox ( ) - > pack_start ( * progress_box , false , false ) ;
2022-04-15 12:25:18 -04:00
set_tooltip ( normalize_checkbox , _ ( " <b>When enabled</b>, the audio is normalized to 0dBFS during export. " ) ) ;
set_tooltip ( copy_video_codec_checkbox , _ ( " <b>When enabled</b>, the video is not re-encoded, but the original video codec is reused. In some cases this can lead to audio/video synchronization issues. This also only works if the exported range is not longer than the video. Adding black space at the start or end requires encoding. \n <b>When disabled</b>, the video is re-encoded, this may lead to quality loss, but this is the safer option and generally preferable. " ) ) ;
set_tooltip ( meta_checkbox , _ ( " <b>When enabled</b>, information from Menu > Session > Metadata is included in the video file. " ) ) ;
2022-04-18 10:38:16 -04:00
set_tooltip ( audio_sample_rate_combo , _ ( " Select the sample rate of the audio track. Prefer 48kHz, which is the standard for video files. " ) ) ;
set_tooltip ( audio_bitrate_combo , _ ( " Select the bitrate of the audio track in kbit/sec. Higher values result in better quality, but also a larger file. " ) ) ;
2022-04-15 12:25:18 -04:00
2022-02-07 16:46:23 -05:00
outfn_browse_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & ExportVideoDialog : : open_outfn_dialog ) ) ;
invid_browse_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & ExportVideoDialog : : open_invid_dialog ) ) ;
transcode_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & ExportVideoDialog : : launch_export ) ) ;
abort_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & ExportVideoDialog : : abort_clicked ) ) ;
invid_path_entry . signal_changed ( ) . connect ( sigc : : mem_fun ( * this , & ExportVideoDialog : : set_original_file_information ) ) ;
2015-02-27 20:31:08 -05:00
2013-03-12 17:00:09 -04:00
cancel_button = add_button ( Stock : : CANCEL , RESPONSE_CANCEL ) ;
2022-02-07 16:46:23 -05:00
get_action_area ( ) - > pack_start ( transcode_button , false , false ) ;
2013-03-12 17:00:09 -04:00
show_all_children ( ) ;
2020-12-22 13:35:12 -05:00
2022-02-07 16:46:23 -05:00
progress_box - > set_no_show_all ( ) ;
progress_box - > hide ( ) ;
2013-03-12 17:00:09 -04:00
}
ExportVideoDialog : : ~ ExportVideoDialog ( )
{
2022-02-07 16:46:23 -05:00
if ( _transcoder ) {
delete _transcoder ;
_transcoder = 0 ;
}
2013-03-12 17:00:09 -04:00
}
2015-02-27 20:31:08 -05:00
void
2022-02-07 16:46:23 -05:00
ExportVideoDialog : : set_original_file_information ( )
2015-02-27 20:31:08 -05:00
{
2022-02-07 16:46:23 -05:00
assert ( _transcoder = = 0 ) ;
string infile = invid_path_entry . get_text ( ) ;
2015-02-27 20:31:08 -05:00
2022-02-07 16:46:23 -05:00
if ( infile . empty ( ) | | ! Glib : : file_test ( infile , Glib : : FILE_TEST_EXISTS ) ) {
transcode_button . set_sensitive ( false ) ;
2015-02-27 20:31:08 -05:00
return ;
}
2022-02-07 16:46:23 -05:00
_transcoder = new TranscodeFfmpeg ( infile ) ;
transcode_button . set_sensitive ( _transcoder - > probe_ok ( ) ) ;
delete _transcoder ;
_transcoder = 0 ;
2015-02-27 20:31:08 -05:00
}
2022-02-07 16:46:23 -05:00
2015-02-27 17:17:26 -05:00
void
2022-02-07 16:46:23 -05:00
ExportVideoDialog : : apply_state ( TimeSelection & tme , bool range )
2015-02-27 17:17:26 -05:00
{
2022-02-07 16:46:23 -05:00
_export_range = tme ;
2015-02-27 20:31:08 -05:00
2022-02-07 16:46:23 -05:00
outfn_path_entry . set_text ( _session - > session_directory ( ) . export_path ( ) + G_DIR_SEPARATOR + " export.mp4 " ) ;
2015-02-27 17:17:26 -05:00
2015-02-27 20:31:08 -05:00
// TODO remember setting for export-range.. somehow, (let explicit range override)
2022-02-07 16:46:23 -05:00
sampleoffset_t av_offset = ARDOUR_UI : : instance ( ) - > video_timeline - > get_offset ( ) ;
2018-11-29 17:36:19 -05:00
insnd_combo . remove_all ( ) ;
2022-01-26 15:11:15 -05:00
insnd_combo . append ( _ ( " from session start marker to session end marker " ) ) ;
2018-11-29 17:36:19 -05:00
2022-02-07 16:46:23 -05:00
if ( av_offset < 0 ) {
2022-01-26 15:11:15 -05:00
insnd_combo . append ( _ ( " from 00:00:00:00 to the video end " ) ) ;
2015-02-27 17:17:26 -05:00
} else {
2022-01-26 15:11:15 -05:00
insnd_combo . append ( _ ( " from video start to video end " ) ) ;
2015-02-27 17:17:26 -05:00
}
2022-02-07 16:46:23 -05:00
if ( ! _export_range . empty ( ) ) {
2022-01-26 15:11:15 -05:00
insnd_combo . append ( _ ( " Selected range " ) ) ; // TODO show _export_range.start() -> _export_range.end_sample()
2015-02-27 17:17:26 -05:00
}
2022-04-14 19:53:55 -04:00
/* default settings */
2015-02-27 17:17:26 -05:00
if ( range ) {
2022-02-07 16:46:23 -05:00
insnd_combo . set_active ( 2 ) ;
2015-02-27 17:17:26 -05:00
} else {
2022-04-14 19:53:55 -04:00
insnd_combo . set_active ( 1 ) ;
2015-02-27 17:17:26 -05:00
}
2022-04-14 19:53:55 -04:00
audio_bitrate_combo . set_active ( 0 ) ;
audio_sample_rate_combo . set_active ( 0 ) ;
2022-02-07 16:46:23 -05:00
normalize_checkbox . set_active ( false ) ;
2022-04-14 19:53:55 -04:00
copy_video_codec_checkbox . set_active ( false ) ;
2022-02-07 16:46:23 -05:00
meta_checkbox . set_active ( false ) ;
2022-04-14 19:53:55 -04:00
/* set original video file */
2022-02-07 16:46:23 -05:00
XMLNode * node = _session - > extra_xml ( X_ ( " Videotimeline " ) ) ;
bool filenameset = false ;
2015-02-27 17:17:26 -05:00
if ( node ) {
2022-02-07 16:46:23 -05:00
string filename ;
if ( node - > get_property ( X_ ( " OriginalVideoFile " ) , filename ) ) {
if ( Glib : : file_test ( filename , Glib : : FILE_TEST_EXISTS ) ) {
2015-02-27 17:17:26 -05:00
invid_path_entry . set_text ( filename ) ;
filenameset = true ;
}
}
2016-08-29 03:18:45 -04:00
bool local_file ;
if ( ! filenameset & & node - > get_property ( X_ ( " Filename " ) , filename ) & &
node - > get_property ( X_ ( " LocalFile " ) , local_file ) & & local_file ) {
2022-02-07 16:46:23 -05:00
if ( filename . at ( 0 ) ! = G_DIR_SEPARATOR ) {
filename = Glib : : build_filename ( _session - > session_directory ( ) . video_path ( ) , filename ) ;
2015-02-27 17:17:26 -05:00
}
2022-02-07 16:46:23 -05:00
if ( Glib : : file_test ( filename , Glib : : FILE_TEST_EXISTS ) ) {
2015-02-27 17:17:26 -05:00
invid_path_entry . set_text ( filename ) ;
filenameset = true ;
}
}
2015-03-23 22:28:07 -04:00
}
2022-02-07 16:46:23 -05:00
2015-03-23 22:28:07 -04:00
if ( ! filenameset ) {
invid_path_entry . set_text ( X_ ( " " ) ) ;
2015-02-27 17:17:26 -05:00
}
2022-04-14 19:53:55 -04:00
/* apply saved state, if any */
2015-02-27 17:17:26 -05:00
node = _session - > extra_xml ( X_ ( " Videoexport " ) ) ;
if ( node ) {
2022-04-14 19:53:55 -04:00
bool yn ;
int num ;
2022-02-07 16:46:23 -05:00
string str ;
2016-08-29 03:18:45 -04:00
if ( node - > get_property ( X_ ( " NormalizeAudio " ) , yn ) ) {
normalize_checkbox . set_active ( yn ) ;
}
2022-04-14 19:53:55 -04:00
if ( node - > get_property ( X_ ( " CopyVCodec " ) , yn ) ) {
copy_video_codec_checkbox . set_active ( yn ) ;
}
2016-08-29 03:18:45 -04:00
if ( node - > get_property ( X_ ( " Metadata " ) , yn ) ) {
meta_checkbox . set_active ( yn ) ;
}
2022-04-14 19:53:55 -04:00
if ( node - > get_property ( X_ ( " ExportRange " ) , num ) ) {
if ( ! range & & num > = 0 & & num < 1 ) {
insnd_combo . set_active ( num ) ;
}
}
if ( node - > get_property ( X_ ( " AudioSRChoice " ) , num ) ) {
if ( num > = 0 & & num < 3 ) {
audio_sample_rate_combo . set_active ( num ) ;
}
}
if ( node - > get_property ( X_ ( " OutputFile " ) , str ) ) {
outfn_path_entry . set_text ( str ) ;
}
if ( node - > get_property ( X_ ( " AudioBitrate " ) , str ) ) {
Gtkmm2ext : : set_active_text_if_present ( audio_bitrate_combo , str ) ;
}
2015-02-27 17:17:26 -05:00
}
2015-02-27 20:31:08 -05:00
2022-02-07 16:46:23 -05:00
set_original_file_information ( ) ;
2015-02-27 20:31:08 -05:00
show_all_children ( ) ;
2015-03-24 22:39:47 -04:00
if ( progress_box ) {
2022-02-07 16:46:23 -05:00
progress_box - > hide ( ) ;
2015-03-24 22:39:47 -04:00
}
2015-02-27 17:17:26 -05:00
}
XMLNode &
2022-04-06 23:56:45 -04:00
ExportVideoDialog : : get_state ( ) const
2015-02-27 17:17:26 -05:00
{
XMLNode * node = new XMLNode ( X_ ( " Videoexport " ) ) ;
2022-04-14 19:53:55 -04:00
node - > set_property ( X_ ( " OutputFile " ) , outfn_path_entry . get_text ( ) ) ;
node - > set_property ( X_ ( " ExportRange " ) , insnd_combo . get_active_row_number ( ) ) ;
node - > set_property ( X_ ( " AudioSRChoice " ) , audio_sample_rate_combo . get_active_row_number ( ) ) ;
node - > set_property ( X_ ( " AudioBitrate " ) , audio_bitrate_combo . get_active_text ( ) ) ;
2022-02-07 16:46:23 -05:00
node - > set_property ( X_ ( " NormalizeAudio " ) , normalize_checkbox . get_active ( ) ) ;
2022-04-14 19:53:55 -04:00
node - > set_property ( X_ ( " CopyVCodec " ) , copy_video_codec_checkbox . get_active ( ) ) ;
2022-02-07 16:46:23 -05:00
node - > set_property ( X_ ( " Metadata " ) , meta_checkbox . get_active ( ) ) ;
2015-02-27 17:17:26 -05:00
return * node ;
}
void
2022-02-07 16:46:23 -05:00
ExportVideoDialog : : set_state ( const XMLNode & )
2013-03-12 17:00:09 -04:00
{
}
void
ExportVideoDialog : : abort_clicked ( )
{
2015-02-27 20:31:08 -05:00
_aborted = true ;
if ( _transcoder ) {
2022-02-07 16:46:23 -05:00
_transcoder - > cancel ( ) ;
2013-03-12 17:00:09 -04:00
}
}
void
2017-09-18 12:39:17 -04:00
ExportVideoDialog : : update_progress ( samplecnt_t c , samplecnt_t a )
2013-03-12 17:00:09 -04:00
{
if ( a = = 0 | | c > a ) {
2022-02-07 16:46:23 -05:00
pbar . set_pulse_step ( .1 ) ;
pbar . pulse ( ) ;
2013-04-04 17:40:36 -04:00
} else {
2022-02-07 16:46:23 -05:00
double progress = ( double ) c / ( double ) a ;
progress = progress / ( _normalize ? 3.0 : 2.0 ) ;
if ( _normalize ) {
progress + = 2.0 / 3.0 ;
} else {
progress + = .5 ;
}
2013-04-04 17:40:36 -04:00
pbar . set_fraction ( progress ) ;
2013-03-12 17:00:09 -04:00
}
}
2013-04-03 19:04:27 -04:00
gint
ExportVideoDialog : : audio_progress_display ( )
{
2022-02-07 16:46:23 -05:00
string status_text ;
2022-04-14 19:53:55 -04:00
double progress = - 1.0 ;
2016-02-09 07:19:34 -05:00
switch ( status - > active_job ) {
case ExportStatus : : Normalizing :
2013-04-03 19:04:27 -04:00
pbar . set_text ( _ ( " Normalizing audio " ) ) ;
2022-02-07 16:46:23 -05:00
progress = ( ( float ) status - > current_postprocessing_cycle ) / status - > total_postprocessing_cycles ;
progress = ( progress + 1.0 ) / 3.0 ;
2016-02-09 07:19:34 -05:00
break ;
case ExportStatus : : Exporting :
2013-04-03 19:04:27 -04:00
pbar . set_text ( _ ( " Exporting audio " ) ) ;
2022-02-07 16:46:23 -05:00
progress = ( ( float ) status - > processed_samples_current_timespan ) / status - > total_samples_current_timespan ;
progress = progress / ( _normalize ? 3.0 : 2.0 ) ;
2016-02-09 07:19:34 -05:00
break ;
default :
pbar . set_text ( _ ( " Exporting audio " ) ) ;
break ;
}
if ( progress < _previous_progress ) {
2022-02-07 16:46:23 -05:00
/* Work around gtk bug */
pbar . hide ( ) ;
pbar . show ( ) ;
2016-02-09 07:19:34 -05:00
}
2022-02-07 16:46:23 -05:00
2016-02-09 07:19:34 -05:00
_previous_progress = progress ;
if ( progress > = 0 ) {
2013-04-03 19:04:27 -04:00
pbar . set_fraction ( progress ) ;
2016-02-09 07:19:34 -05:00
} else {
2022-02-07 16:46:23 -05:00
pbar . set_pulse_step ( .1 ) ;
pbar . pulse ( ) ;
2016-02-09 07:19:34 -05:00
}
2013-04-03 19:04:27 -04:00
return TRUE ;
}
2013-03-12 17:00:09 -04:00
void
2022-02-07 16:46:23 -05:00
ExportVideoDialog : : finished ( int status )
2013-03-12 17:00:09 -04:00
{
2022-02-07 16:46:23 -05:00
delete _transcoder ;
_transcoder = 0 ;
if ( _aborted | | status ! = 0 ) {
if ( ! _aborted ) {
2022-04-14 19:53:55 -04:00
ARDOUR_UI : : instance ( ) - > popup_error ( _ ( " Video transcoding failed. " ) ) ;
2022-02-07 16:46:23 -05:00
}
: : g_unlink ( outfn_path_entry . get_text ( ) . c_str ( ) ) ;
: : g_unlink ( _insnd . c_str ( ) ) ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2013-03-12 17:00:09 -04:00
} else {
2022-02-07 16:46:23 -05:00
if ( ! debug_checkbox . get_active ( ) ) {
: : g_unlink ( _insnd . c_str ( ) ) ;
2013-03-12 17:00:09 -04:00
}
2022-02-07 16:46:23 -05:00
Gtk : : Dialog : : response ( RESPONSE_ACCEPT ) ;
2013-03-12 17:00:09 -04:00
}
}
void
ExportVideoDialog : : launch_export ( )
{
2015-02-27 20:31:08 -05:00
/* remember current settings.
* needed because apply_state ( ) acts on both :
* " Videotimeline " and " Video Export " extra XML
* as well as current _session settings
*/
2022-02-07 16:46:23 -05:00
_session - > add_extra_xml ( get_state ( ) ) ;
string outfn = outfn_path_entry . get_text ( ) ;
if ( ! confirm_video_outfn ( * this , outfn ) ) {
return ;
}
vbox - > hide ( ) ;
cancel_button - > hide ( ) ;
transcode_button . hide ( ) ;
pbar . set_size_request ( 300 , - 1 ) ;
pbar . set_text ( _ ( " Exporting Audio... " ) ) ;
progress_box - > show ( ) ;
_aborted = false ;
_normalize = normalize_checkbox . get_active ( ) ;
2013-03-12 17:00:09 -04:00
/* export audio track */
2022-02-07 16:46:23 -05:00
ExportTimespanPtr tsp = _session - > get_export_handler ( ) - > add_timespan ( ) ;
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ExportChannelConfiguration > ccp = _session - > get_export_handler ( ) - > add_channel_config ( ) ;
std : : shared_ptr < ARDOUR : : ExportFilename > fnp = _session - > get_export_handler ( ) - > add_filename ( ) ;
std : : shared_ptr < AudioGrapher : : BroadcastInfo > b ;
2022-02-07 16:46:23 -05:00
2013-04-02 06:27:08 -04:00
XMLTree tree ;
2022-04-14 19:53:55 -04:00
string vtl_normalize = _normalize ? " true " : " false " ;
string vtl_samplerate ;
switch ( audio_sample_rate_combo . get_active_row_number ( ) ) {
case 0 :
vtl_samplerate = string_compose ( " %1 " , _session - > nominal_sample_rate ( ) ) ;
break ;
case 1 :
vtl_samplerate = " 44100 " ;
break ;
default :
vtl_samplerate = " 48000 " ;
break ;
}
2022-02-07 16:46:23 -05:00
2022-04-15 12:25:18 -04:00
/* clang-format off */
2022-02-07 16:46:23 -05:00
tree . read_buffer ( std : : string (
" <?xml version= \" 1.0 \" encoding= \" UTF-8 \" ?> "
" <ExportFormatSpecification name= \" VTL-WAV-16 \" id= \" 3094591e-ccb9-4385-a93f-c9955ffeb1f0 \" > "
" <Encoding id= \" F_WAV \" type= \" T_Sndfile \" extension= \" wav \" name= \" WAV \" has-sample-format= \" true \" channel-limit= \" 256 \" /> "
" <SampleRate rate= \" " + vtl_samplerate + " \" /> "
" <SRCQuality quality= \" SRC_SincBest \" /> "
" <EncodingOptions> "
" <Option name= \" sample-format \" value= \" SF_16 \" /> "
" <Option name= \" dithering \" value= \" D_None \" /> "
" <Option name= \" tag-metadata \" value= \" true \" /> "
" <Option name= \" tag-support \" value= \" false \" /> "
" <Option name= \" broadcast-info \" value= \" false \" /> "
" </EncodingOptions> "
" <Processing> "
" <Normalize enabled= \" " + vtl_normalize + " \" target= \" 0 \" /> "
" <Silence> "
" <Start> "
" <Trim enabled= \" false \" /> "
" <Add enabled= \" false \" > "
" <Duration format= \" Timecode \" hours= \" 0 \" minutes= \" 0 \" seconds= \" 0 \" frames= \" 0 \" /> "
" </Add> "
" </Start> "
" <End> "
" <Trim enabled= \" false \" /> "
" <Add enabled= \" false \" > "
" <Duration format= \" Timecode \" hours= \" 0 \" minutes= \" 0 \" seconds= \" 0 \" frames= \" 0 \" /> "
" </Add> "
" </End> "
" </Silence> "
" </Processing> "
" </ExportFormatSpecification> " )
. c_str ( ) ) ;
2022-04-15 12:25:18 -04:00
/* clang-format on */
2022-02-07 16:46:23 -05:00
2023-02-16 18:33:28 -05:00
std : : shared_ptr < ExportFormatSpecification > fmp = _session - > get_export_handler ( ) - > add_format ( * tree . root ( ) ) ;
2013-03-12 17:00:09 -04:00
/* set up range */
2017-09-18 12:39:17 -04:00
samplepos_t start , end ;
2013-03-12 17:00:09 -04:00
start = end = 0 ;
2022-02-07 16:46:23 -05:00
if ( insnd_combo . get_active_row_number ( ) = = 1 ) {
_transcoder = new TranscodeFfmpeg ( invid_path_entry . get_text ( ) ) ;
if ( _transcoder - > probe_ok ( ) & & _transcoder - > get_fps ( ) > 0 ) {
end = _transcoder - > get_duration ( ) * _session - > nominal_sample_rate ( ) / _transcoder - > get_fps ( ) ;
2013-04-02 06:27:08 -04:00
} else {
warning < < _ ( " Export Video: Cannot query duration of video-file, using duration from timeline instead. " ) < < endmsg ;
2022-02-07 16:46:23 -05:00
end = ARDOUR_UI : : instance ( ) - > video_timeline - > get_duration ( ) ;
}
if ( _transcoder ) {
delete _transcoder ;
_transcoder = 0 ;
2013-03-12 17:00:09 -04:00
}
2022-02-07 16:46:23 -05:00
sampleoffset_t av_offset = ARDOUR_UI : : instance ( ) - > video_timeline - > get_offset ( ) ;
2013-04-02 06:27:08 -04:00
#if 0 /* DEBUG */
printf ( " audio-range -- AV offset: %lld \n " , av_offset ) ;
# endif
2013-03-12 17:00:09 -04:00
if ( av_offset > 0 ) {
2013-04-02 06:27:08 -04:00
start = av_offset ;
2013-03-12 17:00:09 -04:00
}
2013-04-02 06:27:08 -04:00
end + = av_offset ;
2022-02-07 16:46:23 -05:00
} else if ( insnd_combo . get_active_row_number ( ) = = 2 ) {
start = ARDOUR_UI : : instance ( ) - > video_timeline - > quantify_samples_to_apv ( _export_range . start_sample ( ) ) ;
end = ARDOUR_UI : : instance ( ) - > video_timeline - > quantify_samples_to_apv ( _export_range . end_sample ( ) ) ;
2013-09-12 16:46:11 -04:00
}
2013-03-12 17:00:09 -04:00
if ( end < = 0 ) {
2022-02-07 16:46:23 -05:00
start = _session - > current_start_sample ( ) ;
end = _session - > current_end_sample ( ) ;
2013-03-12 17:00:09 -04:00
}
#if 0 /* DEBUG */
2013-04-02 06:27:08 -04:00
printf ( " audio export-range %lld -> %lld \n " , start , end ) ;
2013-03-12 17:00:09 -04:00
# endif
2022-02-07 16:46:23 -05:00
const sampleoffset_t vstart = ARDOUR_UI : : instance ( ) - > video_timeline - > get_offset ( ) ;
const sampleoffset_t vend = vstart + ARDOUR_UI : : instance ( ) - > video_timeline - > get_duration ( ) ;
2013-10-12 15:25:05 -04:00
2022-02-07 16:46:23 -05:00
if ( ( start > = end ) | | ( end < vstart ) | | ( start > vend ) ) {
delete _transcoder ;
_transcoder = 0 ;
2022-04-15 12:25:18 -04:00
ArdourMessageDialog msg ( _ ( " Export Video: The export-range does not include video. " ) ) ;
msg . run ( ) ;
2022-02-07 16:46:23 -05:00
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2013-10-12 15:25:05 -04:00
return ;
}
2022-04-15 12:25:18 -04:00
if ( ( start < vstart | | end > vend ) & & copy_video_codec_checkbox . get_active ( ) ) {
ArdourMessageDialog msg (
_ ( " The export-range is longer than the video file. "
" To add black frames the video has to be encoded. "
" Copying the codec may fail or not produce the intended result. \n "
" Continue anyway? " ) ,
false ,
Gtk : : MESSAGE_INFO ,
Gtk : : BUTTONS_YES_NO ,
true
) ;
msg . set_default_response ( Gtk : : RESPONSE_YES ) ;
if ( msg . run ( ) ! = Gtk : : RESPONSE_YES ) {
delete _transcoder ;
_transcoder = 0 ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
return ;
}
}
2013-03-12 17:00:09 -04:00
tsp - > set_range ( start , end ) ;
tsp - > set_name ( " mysession " ) ;
tsp - > set_range_id ( " session " ) ;
/* add master outs as default */
2022-02-07 16:46:23 -05:00
IO * master_out = _session - > master_out ( ) - > output ( ) . get ( ) ;
2013-03-12 17:00:09 -04:00
if ( ! master_out ) {
warning < < _ ( " Export Video: No Master Out Ports to Connect for Audio Export " ) < < endmsg ;
2022-02-07 16:46:23 -05:00
delete _transcoder ;
_transcoder = 0 ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2013-03-12 17:00:09 -04:00
return ;
}
2022-02-07 16:46:23 -05:00
for ( uint32_t n = 0 ; n < master_out - > n_ports ( ) . n_audio ( ) ; + + n ) {
PortExportChannel * channel = new PortExportChannel ( ) ;
2013-03-12 17:00:09 -04:00
channel - > add_port ( master_out - > audio ( n ) ) ;
ExportChannelPtr chan_ptr ( channel ) ;
ccp - > register_channel ( chan_ptr ) ;
}
/* outfile */
2022-02-07 16:46:23 -05:00
fnp - > set_timespan ( tsp ) ;
fnp - > set_label ( " vtl " ) ;
2013-03-12 17:00:09 -04:00
fnp - > include_label = true ;
2022-02-07 16:46:23 -05:00
_insnd = fnp - > get_path ( fmp ) ;
2013-03-12 17:00:09 -04:00
/* do sound export */
2022-02-07 16:46:23 -05:00
fmp - > set_soundcloud_upload ( false ) ;
_session - > get_export_handler ( ) - > reset ( ) ;
_session - > get_export_handler ( ) - > add_export_config ( tsp , ccp , fmp , fnp , b ) ;
_session - > get_export_handler ( ) - > do_export ( ) ;
2013-04-03 19:04:27 -04:00
status = _session - > get_export_status ( ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
_audio_progress_connection = Glib : : signal_timeout ( ) . connect ( sigc : : mem_fun ( * this , & ExportVideoDialog : : audio_progress_display ) , 100 ) ;
2022-04-14 19:53:55 -04:00
_previous_progress = 0.0 ;
2016-02-09 15:37:28 -05:00
while ( status - > running ( ) ) {
2022-02-07 16:46:23 -05:00
if ( _aborted ) {
status - > abort ( ) ;
}
if ( gtk_events_pending ( ) ) {
2013-04-02 06:27:08 -04:00
gtk_main_iteration ( ) ;
} else {
2013-10-06 05:52:41 -04:00
Glib : : usleep ( 10000 ) ;
2013-04-02 06:27:08 -04:00
}
}
2022-02-07 16:46:23 -05:00
_audio_progress_connection . disconnect ( ) ;
2019-09-17 20:26:03 -04:00
status - > finish ( TRS_UI ) ;
2022-02-07 16:46:23 -05:00
if ( status - > aborted ( ) ) {
: : g_unlink ( _insnd . c_str ( ) ) ;
delete _transcoder ;
_transcoder = 0 ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2013-03-12 17:00:09 -04:00
return ;
}
2013-06-13 20:10:31 -04:00
pbar . set_text ( _ ( " Encoding Video... " ) ) ;
2022-02-07 16:46:23 -05:00
encode_video ( ) ;
2013-03-12 17:00:09 -04:00
}
void
2022-02-07 16:46:23 -05:00
ExportVideoDialog : : encode_video ( )
2013-03-12 17:00:09 -04:00
{
2022-02-07 16:46:23 -05:00
std : : string outfn = outfn_path_entry . get_text ( ) ;
std : : string invid = invid_path_entry . get_text ( ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
_transcoder = new TranscodeFfmpeg ( invid ) ;
if ( ! _transcoder - > ffexec_ok ( ) ) {
2013-04-02 06:27:08 -04:00
/* ffmpeg binary was not found. TranscodeFfmpeg prints a warning */
2022-02-07 16:46:23 -05:00
: : g_unlink ( _insnd . c_str ( ) ) ;
delete _transcoder ;
_transcoder = 0 ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2013-03-12 17:00:09 -04:00
return ;
}
2022-02-07 16:46:23 -05:00
if ( ! _transcoder - > probe_ok ( ) ) {
2013-04-02 06:27:08 -04:00
/* video input file can not be read */
warning < < _ ( " Export Video: Video input file cannot be read. " ) < < endmsg ;
2022-02-07 16:46:23 -05:00
: : g_unlink ( _insnd . c_str ( ) ) ;
delete _transcoder ;
_transcoder = 0 ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2015-02-27 20:31:08 -05:00
return ;
2013-04-02 06:27:08 -04:00
}
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
TranscodeFfmpeg : : FFSettings ffs ; /* = transcoder->default_encoder_settings(); */
ffs . clear ( ) ;
2013-03-12 17:00:09 -04:00
bool map = true ;
2022-02-07 16:46:23 -05:00
sampleoffset_t av_offset = ARDOUR_UI : : instance ( ) - > video_timeline - > get_offset ( ) ;
double duration_s = 0 ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
if ( insnd_combo . get_active_row_number ( ) = = 0 ) {
2013-09-12 16:46:11 -04:00
/* session start to session end */
2022-02-07 16:46:23 -05:00
samplecnt_t duration_f = _session - > current_end_sample ( ) - _session - > current_start_sample ( ) ;
duration_s = ( double ) duration_f / ( double ) _session - > nominal_sample_rate ( ) ;
} else if ( insnd_combo . get_active_row_number ( ) = = 2 ) {
2013-09-12 16:46:11 -04:00
/* selected range */
2022-02-07 16:46:23 -05:00
duration_s = _export_range . length_samples ( ) / ( double ) _session - > nominal_sample_rate ( ) ;
2013-04-02 06:27:08 -04:00
} else {
2013-09-12 16:46:11 -04:00
/* video start to end */
2022-02-07 16:46:23 -05:00
samplecnt_t duration_f = ARDOUR_UI : : instance ( ) - > video_timeline - > get_duration ( ) ;
if ( av_offset < 0 ) {
2013-04-02 06:27:08 -04:00
duration_f + = av_offset ;
2013-03-12 17:00:09 -04:00
}
2022-02-07 16:46:23 -05:00
duration_s = ( double ) duration_f / ( double ) _session - > nominal_sample_rate ( ) ;
2013-04-02 06:27:08 -04:00
}
2022-02-07 16:46:23 -05:00
std : : ostringstream osstream ;
osstream < < duration_s ;
ffs [ " -t " ] = osstream . str ( ) ;
_transcoder - > set_duration ( duration_s * _transcoder - > get_fps ( ) ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
if ( insnd_combo . get_active_row_number ( ) = = 0 | | insnd_combo . get_active_row_number ( ) = = 2 ) {
samplepos_t start , snend ;
const sampleoffset_t vid_duration = ARDOUR_UI : : instance ( ) - > video_timeline - > get_duration ( ) ;
if ( insnd_combo . get_active_row_number ( ) = = 0 ) {
start = _session - > current_start_sample ( ) ;
snend = _session - > current_end_sample ( ) ;
2013-09-12 16:46:11 -04:00
} else {
2022-02-07 16:46:23 -05:00
start = _export_range . start_sample ( ) ;
snend = _export_range . end_sample ( ) ;
2013-09-12 16:46:11 -04:00
}
2013-04-02 06:27:08 -04:00
#if 0 /* DEBUG */
printf ( " AV offset: %lld Vid-len: %lld Vid-end: %lld || start:%lld || end:%lld \n " ,
av_offset , vid_duration , av_offset + vid_duration , start , snend ) ; // XXX
2013-03-12 17:00:09 -04:00
# endif
2013-04-02 06:27:08 -04:00
if ( av_offset > start & & av_offset + vid_duration < snend ) {
2022-02-07 16:46:23 -05:00
_transcoder - > set_leadinout ( ( av_offset - start ) / ( double ) _session - > nominal_sample_rate ( ) ,
( snend - ( av_offset + vid_duration ) ) / ( double ) _session - > nominal_sample_rate ( ) ) ;
2013-04-02 06:27:08 -04:00
} else if ( av_offset > start ) {
2022-02-07 16:46:23 -05:00
_transcoder - > set_leadinout ( ( av_offset - start ) / ( double ) _session - > nominal_sample_rate ( ) , 0 ) ;
2013-04-02 06:27:08 -04:00
} else if ( av_offset + vid_duration < snend ) {
2022-02-07 16:46:23 -05:00
_transcoder - > set_leadinout ( 0 , ( snend - ( av_offset + vid_duration ) ) / ( double ) _session - > nominal_sample_rate ( ) ) ;
_transcoder - > set_avoffset ( ( av_offset - start ) / ( double ) _session - > nominal_sample_rate ( ) ) ;
2013-09-12 16:46:11 -04:00
}
#if 0
else if ( start > av_offset ) {
2017-09-18 12:39:17 -04:00
std : : ostringstream osstream ; osstream < < ( ( start - av_offset ) / ( double ) _session - > nominal_sample_rate ( ) ) ;
2013-09-12 16:46:11 -04:00
ffs [ " -ss " ] = osstream . str ( ) ;
}
# endif
else {
2022-02-07 16:46:23 -05:00
_transcoder - > set_avoffset ( ( av_offset - start ) / ( double ) _session - > nominal_sample_rate ( ) ) ;
2013-04-02 06:27:08 -04:00
}
2013-09-12 16:46:11 -04:00
2013-04-02 06:27:08 -04:00
} else if ( av_offset < 0 ) {
/* from 00:00:00:00 to video-end */
2022-02-07 16:46:23 -05:00
_transcoder - > set_avoffset ( av_offset / ( double ) _session - > nominal_sample_rate ( ) ) ;
2013-03-12 17:00:09 -04:00
}
2018-11-20 18:05:13 -05:00
/* NOTE: type (MetaDataMap) == type (FFSettings) == map<string, string> */
2022-02-07 16:46:23 -05:00
ARDOUR : : SessionMetadata : : MetaDataMap meta = _transcoder - > default_meta_data ( ) ;
if ( meta_checkbox . get_active ( ) ) {
ARDOUR : : SessionMetadata * session_data = ARDOUR : : SessionMetadata : : Metadata ( ) ;
2018-11-20 18:05:13 -05:00
session_data - > av_export_tag ( meta ) ;
2013-03-12 17:00:09 -04:00
}
2022-02-07 16:46:23 -05:00
if ( debug_checkbox . get_active ( ) ) {
_transcoder - > set_debug ( true ) ;
2013-03-12 17:00:09 -04:00
}
2022-04-14 19:53:55 -04:00
if ( copy_video_codec_checkbox . get_active ( ) ) {
ffs [ " -codec:v " ] = " copy " ;
}
2022-04-15 12:25:18 -04:00
if ( audio_bitrate_combo . get_active_row_number ( ) > 0 ) {
2022-04-14 19:53:55 -04:00
ffs [ " -b:a " ] = audio_bitrate_combo . get_active_text ( ) ;
}
2024-10-18 19:51:44 -04:00
_transcoder - > Progress . connect ( * this , invalidator ( * this ) , std : : bind ( & ExportVideoDialog : : update_progress , this , _1 , _2 ) , gui_context ( ) ) ;
_transcoder - > Finished . connect ( * this , invalidator ( * this ) , std : : bind ( & ExportVideoDialog : : finished , this , _1 ) , gui_context ( ) ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
if ( ! _transcoder - > encode ( outfn , _insnd , invid , ffs , meta , map ) ) {
ARDOUR_UI : : instance ( ) - > popup_error ( _ ( " Transcoding failed. " ) ) ;
delete _transcoder ;
_transcoder = 0 ;
Gtk : : Dialog : : response ( RESPONSE_CANCEL ) ;
2015-02-27 20:31:08 -05:00
return ;
}
2013-03-12 17:00:09 -04:00
}
void
ExportVideoDialog : : open_outfn_dialog ( )
{
2022-02-07 16:46:23 -05:00
FileChooserDialog dialog ( _ ( " Save Exported Video File " ) , FILE_CHOOSER_ACTION_SAVE ) ;
2019-01-02 11:37:03 -05:00
Gtkmm2ext : : add_volume_shortcuts ( dialog ) ;
2022-02-07 16:46:23 -05:00
dialog . set_filename ( outfn_path_entry . get_text ( ) ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
dialog . add_button ( Stock : : CANCEL , RESPONSE_CANCEL ) ;
dialog . add_button ( Stock : : OK , RESPONSE_OK ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
int result = dialog . run ( ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
if ( result = = RESPONSE_OK ) {
std : : string filename = dialog . get_filename ( ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
if ( filename . length ( ) ) {
2013-03-12 17:00:09 -04:00
outfn_path_entry . set_text ( filename ) ;
}
2022-02-07 16:46:23 -05:00
std : : string ext = get_file_extension ( filename ) ;
if ( ext ! = " mp4 " | | ext ! = " mov " | | ext ! = " mkv " ) {
dialog . hide ( ) ;
ArdourMessageDialog msg ( _ ( " The file extension defines the format and codec. \n Prefer to use .mp4, .mov or .mkv. Otherwise encoding may fail. " ) ) ;
msg . run ( ) ;
}
2013-03-12 17:00:09 -04:00
}
}
void
ExportVideoDialog : : open_invid_dialog ( )
{
2022-02-07 16:46:23 -05:00
FileChooserDialog dialog ( _ ( " Input Video File " ) , FILE_CHOOSER_ACTION_OPEN ) ;
2019-01-02 11:37:03 -05:00
Gtkmm2ext : : add_volume_shortcuts ( dialog ) ;
2022-02-07 16:46:23 -05:00
dialog . set_filename ( invid_path_entry . get_text ( ) ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
dialog . add_button ( Stock : : CANCEL , RESPONSE_CANCEL ) ;
dialog . add_button ( Stock : : OK , RESPONSE_OK ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
int result = dialog . run ( ) ;
2013-03-12 17:00:09 -04:00
2022-02-07 16:46:23 -05:00
if ( result = = RESPONSE_OK ) {
std : : string filename = dialog . get_filename ( ) ;
if ( ! filename . empty ( ) ) {
2013-03-12 17:00:09 -04:00
invid_path_entry . set_text ( filename ) ;
}
}
}