mirror of
https://github.com/farfalleflickan/cmyflix.git
synced 2025-02-05 08:45:31 +00:00
Added support for webm/ogv/mkv files
This commit is contained in:
parent
6e5a709e22
commit
d4b22ce191
@ -37,7 +37,7 @@ Either install from source with make install OR use a pre-compiled package from
|
||||
Beware, the pre-compiled `deb` file is built using the default `libcurl4-openssl-dev` backend.
|
||||
|
||||
# Requirements to run:
|
||||
cmyflix uses libcjson(>=1.7.15), libcurl(>=7.68), imagemagick, ffmpeg and a TMDB api key. Please do also note that cmyflix searches for `mp4` files due to the usage of HTML5 and its supported formats.
|
||||
cmyflix uses libcjson(>=1.7.15), libcurl(>=7.68), imagemagick, ffmpeg and a TMDB api key. Please do also note that cmyflix searches for `mp4`,`mkv`,`ogv` and `webm` files due to the usage of HTML5 and its supported formats.
|
||||
|
||||
# Configuration & usage:
|
||||
For starters, cmyflix looks for `cmyflix.cfg` first in the same folder as the binary, then in `$HOME/.config/cmyflix/` and lastly in `/etc/cmyflix/`. Same thing applies for folder `html` and its contents.
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "iofiles.h"
|
||||
|
||||
// Own implementation with opendir/readdir. nftw might be faster? Dunno, nftw seemed slower in tests
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode mode, bool recursive) {
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char **searchStrs, ioMode mode, bool recursive) {
|
||||
DIR *directory = opendir(dirPath);
|
||||
if (directory == NULL) {
|
||||
printError("find warning", false, HYEL, "failed while opening directory \"%s\";\nError: %s;\n", dirPath, strerror(errno));
|
||||
@ -46,7 +46,7 @@ struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode m
|
||||
list = initList(list, NULL, 0);
|
||||
addData(list, path);
|
||||
}
|
||||
fileList *temp = find(conf, path, searchStr, mode, recursive);
|
||||
fileList *temp = find(conf, path, searchStrs, mode, recursive);
|
||||
if (temp != NULL) {
|
||||
list = joinLists(list, temp);
|
||||
}
|
||||
@ -56,7 +56,9 @@ struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode m
|
||||
addData(newFile, fileP->d_name);
|
||||
list=joinLists(newFile, list);
|
||||
}
|
||||
} else if (strstr(fileP->d_name, searchStr) && (mode & FI_MODE)!=0) { // if filename matches the string we looking for AND in file mode
|
||||
} else if ((mode & FI_MODE)!=0) { // if filename matches the string we looking for AND in file mode
|
||||
for (char **currentStr = searchStrs; *currentStr != NULL; currentStr++) {
|
||||
if (strstr(fileP->d_name, *currentStr) != NULL) {
|
||||
char **fileMatch = NULL;
|
||||
if ((mode & TV_MODE)!=0) { // if TV mode bit set
|
||||
// if ( conf->tvDB_exists==true && (mode & CK_MODE)!=0 && strstr(conf->tvDB_str, path)!=NULL) { // if filename already in database & in 'check mode'
|
||||
@ -86,6 +88,9 @@ struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode m
|
||||
list=joinLists(newFile, list);
|
||||
}
|
||||
freeStrArr(fileMatch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tryFree(path);
|
||||
}
|
||||
|
@ -9,4 +9,4 @@ typedef enum {
|
||||
TV_MODE=1 << 3 // TV show mode
|
||||
} ioMode;
|
||||
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char *searchStr, ioMode mode, bool recursive);
|
||||
struct fileList *find(progConfig *conf, char *dirPath, char **searchStrs, ioMode mode, bool recursive);
|
||||
|
22
src/movies.c
22
src/movies.c
@ -15,7 +15,7 @@ struct fileList *createMoviesDB(progConfig *conf) {
|
||||
char *infoStr="building home movies' database...";
|
||||
if (conf->homeMovies==false) {
|
||||
infoStr="building movies' database...";
|
||||
folders=find(conf, conf->MoviesPath, "", DI_MODE, false);
|
||||
folders=find(conf, conf->MoviesPath, (char *[]){"", NULL}, DI_MODE, false);
|
||||
}
|
||||
printInfo("createMoviesDB info", true, "%s\n", infoStr);
|
||||
|
||||
@ -432,11 +432,25 @@ void *movieHTML(void *threadArg) {
|
||||
}
|
||||
printInfo("movieHTML info", true, "building HTML for \"%s\";\n", movieName);
|
||||
|
||||
size_t tempStrSize=strlen(MOVIE_HTML_VIDEO)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
char *tempStr=NULL;
|
||||
size_t tempStrSize = 0;
|
||||
if (strstr(movieFile, ".webm") != NULL) {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO_WEBM)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO_WEBM, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
} else if (strstr(movieFile, ".ogv") != NULL) {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO_OGG)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO_OGG, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
} else if (strstr(movieFile, ".mp4") != NULL) {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO_MP4)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO_MP4, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
} else {
|
||||
tempStrSize=strlen(MOVIE_HTML_VIDEO)+intSize(thisThread->id)*3+strlen(moviePoster)+strlen(movieFile)+strlen(movieName)*2+1;
|
||||
mallocMacro(tempStr, tempStrSize, "movieHTML error");
|
||||
|
||||
snprintf(tempStr, tempStrSize, MOVIE_HTML_VIDEO, thisThread->id, movieName, moviePoster, movieName, thisThread->id, thisThread->id, movieFile);
|
||||
}
|
||||
addData(thisThread->list, tempStr);
|
||||
|
||||
cJSON *currSub=NULL;
|
||||
@ -454,7 +468,7 @@ void *movieHTML(void *threadArg) {
|
||||
}
|
||||
tryFree(subPath);
|
||||
}
|
||||
addData(thisThread->list, MOVIE_HTML_VIDEO_BOT);
|
||||
addData(thisThread->list, MOVIE_HTML_VIDEO_BOTTOM);
|
||||
tryFree(moviePoster);
|
||||
tryFree(movieFile);
|
||||
tryFree(tempStr);
|
||||
|
@ -4,11 +4,14 @@
|
||||
|
||||
#define MOVIE_HTML_TOP "<!DOCTYPE html>\n<html>\n<head>\n<title>cmyflix</title>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">\n<meta name=\"description\" content=\"Daria Rostirolla\">\n<meta name=\"keywords\" content=\"HTML, CSS\">\n<meta name=\"author\" content=\"Daria Rostirolla\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<link href=\"css/movie.css\" rel=\"stylesheet\" type=\"text/css\">\n<link rel=\"icon\" type=\"image/png\" href=\"img/favicon.png\">\n</head>\n<body>\n<script type=\"text/javascript\" src=\"js/Mscript.js\"></script><div id=\"wrapper\">"
|
||||
|
||||
#define MOVIE_HTML_VIDEO "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/mp4\">"
|
||||
#define MOVIE_HTML_VIDEO "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\">"
|
||||
#define MOVIE_HTML_VIDEO_WEBM "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/webm\">"
|
||||
#define MOVIE_HTML_VIDEO_MP4 "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/mp4\">"
|
||||
#define MOVIE_HTML_VIDEO_OGG "<div class=\"movieDiv\">\n<input id=\"A%d\" class=\"myBtn\" alt=\"%s\" onclick=\"javascript:showModal(this)\" type=\"image\" src=\"%s\" onload=\"javascript:setAlt(this, '%s')\">\n<div id=\"B%d\" class=\"modal\">\n<div class=\"modal-content\">\n<video id=\"C%d\" class=\"video_player\" controls preload=\"none\">\n<source src=\"%s\" type=\"video/ogg\">"
|
||||
|
||||
#define MOVIE_HTML_SUBS "\n<track src=\"%s\" kind=\"subtitles\" label=\"%s\">"
|
||||
|
||||
#define MOVIE_HTML_VIDEO_BOT "\n</video>\n<span onclick=\"javascript:hideModal()\" class=\"close\">×</span>\n</div>\n</div>\n</div>"
|
||||
#define MOVIE_HTML_VIDEO_BOTTOM "\n</video>\n<span onclick=\"javascript:hideModal()\" class=\"close\">×</span>\n</div>\n</div>\n</div>"
|
||||
|
||||
#define MOVIE_HTML_BOT "\n<div id=\"paddingDiv\">\n</div>\n</div>\n</body>\n</html>"
|
||||
|
||||
|
37
src/tvshow.c
37
src/tvshow.c
@ -15,7 +15,7 @@
|
||||
// JSON maker
|
||||
struct fileList *createTVShowDB(progConfig *conf) {
|
||||
printInfo("createTVShowDB info", true, "building TV shows' database...\n");
|
||||
fileList *showFolders=find(conf, conf->TVpath, "", DI_MODE, false);
|
||||
fileList *showFolders=find(conf, conf->TVpath, (char *[]){"", NULL}, DI_MODE, false);
|
||||
|
||||
if (showFolders != NULL ) {
|
||||
int foldersListSize=showFolders->listSize, i=0;
|
||||
@ -119,7 +119,7 @@ void *findSeasons(void *threadArg) { // runs in Show.Name folder and spawns thre
|
||||
}
|
||||
// Find all the seasons of the current tv show
|
||||
printInfo("findSeasons info", true, "looking for seasons' folders in: \"%s\";\n", showPath);
|
||||
fileList *seasonsList = find(conf, showPath, "", DI_MODE, false); // get all seasons folders
|
||||
fileList *seasonsList = find(conf, showPath, (char *[]){"", NULL}, DI_MODE, false); // get all seasons folders
|
||||
|
||||
if (seasonsList!=NULL && seasonsList->data!=NULL) {
|
||||
bool showHasExtras=false;
|
||||
@ -276,7 +276,7 @@ void *findSeasons(void *threadArg) { // runs in Show.Name folder and spawns thre
|
||||
tryFree(extrasJSONStr);
|
||||
tryFree(tempShowJSONStr);
|
||||
} else {
|
||||
printError("findSeasons warning", false, HYEL, "please note, could not find any \".%s\" in path \"%s\"\n", videoExt, showPath);
|
||||
printError("findSeasons warning", false, HYEL, "please note, could not find any in path \"%s\"\n", showPath);
|
||||
}
|
||||
} else {
|
||||
printError("findSeasons warning", false, HYEL, "please note, path \"%s\" is empty!\n", showPath);
|
||||
@ -432,9 +432,13 @@ void *findEpisodes(void *threadArg) { // find files of 'this' season
|
||||
|
||||
if (epName==NULL) {
|
||||
if (temp->dataSize>5 && seasonExtra==false) {
|
||||
if (strcmp(temp->data[6], videoExt)==0) {
|
||||
for (char **currentStr = videoExt; *currentStr != NULL; currentStr++) {
|
||||
if (strcmp(temp->data[6], *currentStr)==0) {
|
||||
epName=removeExtension(temp->data[2]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (epName==NULL) {
|
||||
epName=removeExtension(temp->data[6]);
|
||||
}
|
||||
} else {
|
||||
@ -849,12 +853,35 @@ void episodeHTML(fileList *this_show, progConfig *conf, cJSON *episode, int *cur
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_SPAN, this_episodeName);
|
||||
addData(this_show, tempStr);
|
||||
|
||||
if (strstr(this_file, ".webm") != NULL) {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO_WEBM)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO_WEBM, *uuid, *uuidEpisode, this_file);
|
||||
} else if (strstr(this_file, ".ogv") != NULL) {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO_OGG)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO_OGG, *uuid, *uuidEpisode, this_file);
|
||||
} else if (strstr(this_file, ".mp4") != NULL) {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO_MP4)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO_MP4, *uuid, *uuidEpisode, this_file);
|
||||
} else {
|
||||
tempStrSize=intSize(*uuid)+intSize(*uuidEpisode)+strlen(this_file)+strlen(SHOW_HTML_VIDEO)+1;
|
||||
tempStr=realloc(tempStr, tempStrSize);
|
||||
if (tempStr==NULL) {
|
||||
fatalError_abort("episodeHTML error", "could not realloc;\nError: %s;\n", strerror(errno));
|
||||
}
|
||||
snprintf(tempStr, tempStrSize, SHOW_HTML_VIDEO, *uuid, *uuidEpisode, this_file);
|
||||
}
|
||||
addData(this_show, tempStr);
|
||||
|
||||
cJSON *currSub=NULL;
|
||||
|
@ -26,7 +26,10 @@
|
||||
|
||||
#define SHOW_HTML_SPAN "<span onclick=\"javascript:hideVideoModal()\" class=\"close\">×</span>\n<p id=\"epTitle\">%s</p>"
|
||||
|
||||
#define SHOW_HTML_VIDEO "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/mp4\">"
|
||||
#define SHOW_HTML_VIDEO "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\">"
|
||||
#define SHOW_HTML_VIDEO_WEBM "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/webm\">"
|
||||
#define SHOW_HTML_VIDEO_MP4 "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/mp4\">"
|
||||
#define SHOW_HTML_VIDEO_OGG "\n<video id=\"F%d_%d\" class=\"video_player\" controls preload=\"none\" onplaying=\"javascript:rezHandler()\">\n<source src=\"../%s\" type=\"video/ogg\">"
|
||||
|
||||
#define SHOW_HTML_SUBS "\n<track src=\"../%s\" kind=\"subtitles\" label=\"%s\">"
|
||||
|
||||
|
@ -603,7 +603,7 @@ char *randStr(size_t size) {
|
||||
char *getSubs(progConfig *conf, char *fileStr, char *filePath) {
|
||||
char *epSubs=NULL;
|
||||
char *fileName=removeExtension(fileStr);
|
||||
fileList *subs=find(conf, filePath, fileName, FI_MODE, false);
|
||||
fileList *subs=find(conf, filePath, (char *[]){fileName, NULL}, FI_MODE, false);
|
||||
|
||||
for (fileList *tempSub=subs; tempSub!=NULL; tempSub=tempSub->next) {
|
||||
if (tempSub->dataSize>2) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define tmdbTV_ID "https://api.themoviedb.org/3/search/tv?page=1&query=" // name&api_key=blah +opts
|
||||
#define tmdbTV_Opts "&language=en" //to find the ID based on name
|
||||
#define tmdbImg "https://image.tmdb.org/t/p/original"
|
||||
#define videoExt "mp4"
|
||||
#define videoExt (char *[]){"mp4", "mkv", "ogv", "webm", NULL}
|
||||
#define subExt1 "srt"
|
||||
#define subExt2 "vtt"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user