Use pipe through ffmpeg, use glib to write output
This is intended to fix an issue with odd filenames on Windows, particularly forward and backwards single quotes as part of a filename. Previously the filename was passed as parameter to ffmpeg as UTF-8 string to SystemExec::make_wargs, which is fragile on Windows in absence of a execve() call.
This commit is contained in:
parent
16a476ee5f
commit
bb4394b8a5
@ -398,7 +398,11 @@ ExportGraphBuilder::Encoder::init_writer (boost::shared_ptr<AudioGrapher::CmdPip
|
||||
argp[a++] = strdup ("-i");
|
||||
argp[a++] = strdup ("pipe:0");
|
||||
|
||||
argp[a++] = strdup ("-y");
|
||||
argp[a++] = strdup ("-f");
|
||||
argp[a++] = strdup ("mp3");
|
||||
argp[a++] = strdup ("-acodec");
|
||||
argp[a++] = strdup ("mp3");
|
||||
|
||||
if (quality <= 0) {
|
||||
/* variable rate, lower is better */
|
||||
snprintf (tmp, sizeof(tmp), "%d", -quality);
|
||||
@ -422,16 +426,14 @@ ExportGraphBuilder::Encoder::init_writer (boost::shared_ptr<AudioGrapher::CmdPip
|
||||
argp[a++] = SystemExec::format_key_value_parameter (it->first.c_str(), it->second.c_str());
|
||||
}
|
||||
|
||||
argp[a++] = strdup (writer_filename.c_str());
|
||||
argp[a++] = strdup ("pipe:1");
|
||||
argp[a] = (char *)0;
|
||||
|
||||
/* argp is free()d in ~SystemExec,
|
||||
* SystemExec is deleted when writer is destroyed */
|
||||
ARDOUR::SystemExec* exec = new ARDOUR::SystemExec (ffmpeg_exe, argp, true);
|
||||
|
||||
PBD::info << "Encode command: { " << exec->to_s () << "}" << endmsg;
|
||||
if (exec->start (SystemExec::MergeWithStdin)) {
|
||||
throw ExportFailed ("External encoder (ffmpeg) cannot be started.");
|
||||
}
|
||||
writer.reset (new AudioGrapher::CmdPipeWriter<T> (exec, writer_filename));
|
||||
writer->FileWritten.connect_same_thread (copy_files_connection, boost::bind (&ExportGraphBuilder::Encoder::copy_files, this, _1));
|
||||
}
|
||||
|
@ -3,14 +3,18 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <glib.h>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include "audiographer/flag_debuggable.h"
|
||||
#include "audiographer/sink.h"
|
||||
#include "audiographer/types.h"
|
||||
|
||||
#include "pbd/gstdio_compat.h"
|
||||
#include "pbd/signals.h"
|
||||
#include "pbd/system_exec.h"
|
||||
|
||||
#include "ardour/system_exec.h"
|
||||
#include "ardour/export_failed.h"
|
||||
|
||||
namespace AudioGrapher
|
||||
{
|
||||
@ -25,16 +29,31 @@ class CmdPipeWriter
|
||||
, public FlagDebuggable<>
|
||||
{
|
||||
public:
|
||||
CmdPipeWriter (PBD::SystemExec* proc, std::string const& path)
|
||||
CmdPipeWriter (ARDOUR::SystemExec* proc, std::string const& path)
|
||||
: samples_written (0)
|
||||
, _proc (proc)
|
||||
, _path (path)
|
||||
{
|
||||
add_supported_flag (ProcessContext<T>::EndOfInput);
|
||||
|
||||
proc->ReadStdout.connect_same_thread (exec_connections, boost::bind (&CmdPipeWriter::write_ffile, this, _1, _2));
|
||||
proc->Terminated.connect_same_thread (exec_connections, boost::bind (&CmdPipeWriter::close_ffile, this));
|
||||
|
||||
encoder_file = g_fopen (path.c_str(), "wb");
|
||||
|
||||
if (!encoder_file) {
|
||||
throw ARDOUR::ExportFailed ("Output file cannot be written to.");
|
||||
}
|
||||
|
||||
if (proc->start (ARDOUR::SystemExec::IgnoreAndClose)) {
|
||||
fclose (encoder_file);
|
||||
throw ARDOUR::ExportFailed ("External encoder (ffmpeg) cannot be started.");
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~CmdPipeWriter () {
|
||||
delete _proc;
|
||||
assert (!encoder_file);
|
||||
}
|
||||
|
||||
samplecnt_t get_samples_written() const { return samples_written; }
|
||||
@ -65,7 +84,6 @@ public:
|
||||
|
||||
if (c.has_flag(ProcessContext<T>::EndOfInput)) {
|
||||
_proc->close_stdin ();
|
||||
FileWritten (_path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +97,20 @@ private:
|
||||
samplecnt_t samples_written;
|
||||
PBD::SystemExec* _proc;
|
||||
std::string _path;
|
||||
|
||||
FILE* encoder_file;
|
||||
|
||||
void write_ffile (std::string d, size_t s) {
|
||||
fwrite (d.c_str(), sizeof(char), s, encoder_file);
|
||||
}
|
||||
|
||||
void close_ffile () {
|
||||
fclose (encoder_file);
|
||||
encoder_file = 0;
|
||||
FileWritten (_path);
|
||||
}
|
||||
|
||||
PBD::ScopedConnectionList exec_connections;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user