/**
* ======================== legal notice ======================
*
* File: MediaFactory.cc
* Created: 2. Juli 2012, 15
* Author: Geronimo
* Project: libMediaScan: mediatypes and media scanning
*
* CMP - compound media player
*
* is a client/server mediaplayer intended to play any media from any workstation
* without the need to export or mount shares. cmps is an easy to use backend
* with a (ready to use) HTML-interface. Additionally the backend supports
* authentication via HTTP-digest authorization.
* cmpc is a client with vdr-like osd-menues.
*
* Copyright (c) 2012 Reinhard Mantey, some rights reserved!
* published under Creative Commons by-sa
* For details see http://creativecommons.org/licenses/by-sa/3.0/
*
* The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
*
* --------------------------------------------------------------
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
cMediaFactory::cMediaFactory(const cServerConfig &sc)
: config(sc)
, baseDirectory(sc.DocumentRoot())
, scratch(NULL)
, scratchSize(1024)
{
scratch = (char *)malloc(scratchSize);
}
cMediaFactory::~cMediaFactory()
{
free(scratch);
}
void cMediaFactory::SetBaseDirectory(const cFile &dir)
{
if (!dir.IsDirectory()) {
esyslog("ERROR: attempt to set base directory to a file (%s)", dir.Name());
return;
}
baseDirectory = dir;
}
int cMediaFactory::createMedia(void *opaque, cFile *Parent, const char *Name)
{
if (!opaque) return -1;
cMediaFactory *mf = (cMediaFactory *) opaque;
return mf->CreateMedia(Parent, Name);
}
int cMediaFactory::CreateMedia(const cFile *Parent, const char *Name)
{
cFile *curFile = new cFile(*Parent, Name);
const char *mimeType = NULL;
cAbstractMedia *rv = NULL;
if (!curFile) {
esyslog("ERROR: out of memory!");
return -1;
}
if (!curFile->Exists()) {
delete curFile;
return -1;
}
if (curFile->IsDirectory()) {
static const char *keyFiles[] = { "001.vdr", "00001.ts", "VIDEO_TS/VIDEO_TS.IFO", NULL };
cFile *tmp;
const char *check;
int n=0;
for (const char **kf = keyFiles; kf && *kf; ++kf, ++n) {
tmp = new cFile(*curFile, *kf);
check = tmp ? tmp->AbsolutePath() : NULL;
if (tmp->Exists() && tmp->IsFile() && !tmp->IsDirectory()) {
switch (n) {
case 0: rv = new cLegacyVdrRecording(*curFile); break;
case 1: rv = new cVdrRecording(*curFile); break;
default: rv = new cDVDImage(*curFile); break;
}
}
delete tmp;
}
if (!rv) curFile->VisitFiles(createMedia, this);
}
else {
const char *extension = strrchr(Name, '.');
if (!extension) {
delete curFile;
return -1;
}
++extension;
mimeType = cMovie::ContentType(extension);
if (mimeType) rv = new cMovie(*curFile, mimeType);
else {
mimeType = cAudio::ContentType(extension);
if (mimeType) rv = new cAudio(*curFile, mimeType);
else {
mimeType = cPicture::ContentType(extension);
if (mimeType) rv = new cPicture(*curFile, mimeType);
}
}
}
delete curFile;
if (rv) {
if (config.WantExtendedScan() && rv->NeedsFurtherScan()) {
rv->Refresh();
Scan4MetaData(rv);
}
mediaPool->push_back(rv);
return 0;
}
return -1;
}
void cMediaFactory::Scan4Media(cManagedVector& pool)
{
if (!baseDirectory.Exists() || !baseDirectory.IsDirectory()) return;
baseDirectory.SetVirtualRoot();
mediaPool = &pool;
baseDirectory.VisitFiles(createMedia, this);
}
void cMediaFactory::Scan4MetaData(cAbstractMedia* media)
{
cCommandReader *cr = new cCommandReader("/usr/bin/mediainfo");
cMediainfoReader *mir = new cMediainfoReader(new cLineReader(cr));
cMediainfoReader::InfoEntry *ie;
cr->AddCommandParameter(media->KeyFile());
while ((ie = mir->ReadEntry())) {
media->AddMeta(ie);
}
delete mir;
}