Skip to content

Instantly share code, notes, and snippets.

@nu774
Created April 10, 2014 13:15
Show Gist options
  • Save nu774/10381075 to your computer and use it in GitHub Desktop.
Save nu774/10381075 to your computer and use it in GitHub Desktop.
#include <cstdio>
#include <string>
#include <vector>
#include <memory>
#include <sstream>
#include <windows.h>
#include <shlwapi.h>
#include <QTML.h>
#include <Movies.h>
#include <QuickTimeComponents.h>
struct QTMLRAII {
QTMLRAII() {
InitializeQTML(0);
EnterMovies();
}
~QTMLRAII() {
ExitMovies();
TerminateQTML();
}
};
#define CHECKQ(expr) \
do { \
long err = expr; \
if (err) { \
std::stringstream ss; \
ss << "ERROR " << err << ": " << #expr; \
throw std::runtime_error(ss.str()); \
} \
} while (0)
static
std::wstring GetFullPathNameX(const std::wstring &path)
{
DWORD length = GetFullPathNameW(path.c_str(), 0, 0, 0);
std::vector<wchar_t> buffer(length);
length = GetFullPathNameW(path.c_str(), buffer.size(), &buffer[0], 0);
return std::wstring(&buffer[0], &buffer[length]);
}
static
std::shared_ptr<const __CFString> W2CF(const std::wstring &s)
{
const UniChar *ucs = reinterpret_cast<const UniChar *>(s.c_str());
CFStringRef sref = CFStringCreateWithCharacters(0, ucs, s.size());
std::shared_ptr<const __CFString> cfs(sref, CFRelease);
return cfs;
}
class DataReference {
std::shared_ptr<Ptr> handle_;
OSType type_;
public:
DataReference(const std::wstring &path)
{
std::shared_ptr<const __CFString> cfpath(W2CF(GetFullPathNameX(path)));
Handle dataRef = 0;
CHECKQ(QTNewDataReferenceFromFullPathCFString(
cfpath.get(), kQTNativeDefaultPathStyle, 0, &dataRef, &type_));
handle_ = std::shared_ptr<Ptr>(dataRef, DisposeHandle);
}
Handle handle() { return handle_.get(); }
OSType type() { return type_; }
};
int wmain(int argc, wchar_t **argv)
{
if (argc < 3) {
std::fprintf(stderr, "usage: %ls INFILE OUTFILE\n", argv[0]);
return 1;
}
try {
QTMLRAII qtml;
DataReference iDataRef(argv[1]);
DataReference oDataRef(argv[2]);
short resID = 0;
Movie movie, newMovie;
CHECKQ(NewMovieFromDataRef(&movie, newMovieActive, &resID,
iDataRef.handle(), iDataRef.type()));
std::shared_ptr<MovieType*> moviePtr(movie, DisposeMovie);
newMovie = FlattenMovieDataToDataRef(movie,
flattenAddMovieToDataFork,
oDataRef.handle(),
oDataRef.type(),
'TVOD',
smSystemScript,
createMovieFileDeleteCurFile);
if (!newMovie)
throw std::runtime_error("FlattenMovieDataToDataRef()");
DisposeMovie(newMovie);
std::fputs("Done\n", stderr);
} catch (const std::exception &e) {
std::fprintf(stderr, "%s\n", e.what());
return 2;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment