Created
April 10, 2014 13:15
-
-
Save nu774/10381075 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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