/** * ======================== legal notice ====================== * * File: MediaFactory.cc * Created: 2. Juli 2012, 15:43 * Author: Geronimo * Project: libfsScan: mediatypes and filesystem 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 cMediaFactory::cMediaFactory(const char *BaseDirectory) : baseDirectory(BaseDirectory ? strdup(BaseDirectory) : NULL) , scratch(NULL) , scratchSize(1024) { if (baseDirectory && *(baseDirectory + strlen(baseDirectory) - 1) == '/') *(baseDirectory + strlen(baseDirectory) - 1) = 0; scratch = (char *)malloc(scratchSize); } cMediaFactory::~cMediaFactory() { free(scratch); free(baseDirectory); } void cMediaFactory::SetBaseDirectory(const char* dir) { if (baseDirectory == dir) return; char *tmp = baseDirectory; baseDirectory = NULL; free(tmp); if (dir) { baseDirectory = strdup(dir); if (*(baseDirectory + strlen(baseDirectory) - 1) == '/') *(baseDirectory + strlen(baseDirectory) - 1) = 0; } } cAbstractMedia *cMediaFactory::CreateMedia(const char* FileOrDirname, struct stat *st) { const char *name = rindex(FileOrDirname, '/') + 1; const char *logical = FileOrDirname + strlen(baseDirectory); const char *mimeType = NULL; cAbstractMedia *rv = NULL; // printf("CreateMedia(%s) ... name=[%s], logical=[%s]\n", FileOrDirname, name, logical); if ((st->st_mode & S_IFMT) == S_IFDIR) { static const char *addons[] = { "/001.vdr", "/00001.ts", "/VIDEO_TS/VIDEO_TS.IFO", "/video_ts/VIDEO_TS.IFO", "/video_ts/video_ts.ifo", NULL }; struct stat stBuf; int n=0; if (scratchSize < (strlen(FileOrDirname) + 32)) { scratchSize += 128; scratch = (char *)realloc(scratch, scratchSize); } if (!scratch) return NULL; for (const char **pa = addons; pa && *pa; ++pa, ++n) { strcpy(scratch, FileOrDirname); strcat(scratch, *pa); if (stat(scratch, &stBuf) < 0) continue; if ((stBuf.st_mode & S_IFMT) == S_IFREG) { if (n < 2) { char *tmp = rindex(scratch, '/'); // filename char *p = tmp; *p = ')'; *(p + 2) = 0; tmp = rindex(scratch, '/'); // ts-directory for (; p > tmp; --p) *(p + 1) = *p; // shift it up one position *(p + 1) = '('; // start of ts-directory *tmp = ' '; // add separator tmp = rindex(scratch, '/'); // name of vdr recording if (tmp) name = tmp + 1; } switch (n) { case 0: rv = new cLegacyVdrRecording(name, logical, FileOrDirname); break; case 1: rv = new cVdrRecording(name, logical, FileOrDirname); break; default: rv = new cDVDImage(name, logical, FileOrDirname); break; } rv->SetLastModified(st->st_mtime); } } } else if ((st->st_mode & S_IFMT) == S_IFREG) { const char *extension = rindex(FileOrDirname, '.'); if (!extension) return NULL; ++extension; mimeType = cMovie::ContentType(extension); if (mimeType) rv = new cMovie(name, logical, FileOrDirname, mimeType); else { mimeType = cAudio::ContentType(extension); if (mimeType) rv = new cAudio(name, logical, FileOrDirname, mimeType); else { mimeType = cPicture::ContentType(extension); if (mimeType) rv = new cPicture(name, logical, FileOrDirname, mimeType); } } if (rv) { rv->SetLastModified(st->st_mtime); rv->SetSize(st->st_size); } } return rv; }