* Add SRT subtitle support using Samsung's method.
This commit is contained in:
parent
4efa9d06ac
commit
f7e525019a
@ -23,6 +23,7 @@
|
||||
#include "utils.h"
|
||||
#include "sql.h"
|
||||
#include "scanner.h"
|
||||
#include "metadata.h"
|
||||
#include "albumart.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -278,6 +279,8 @@ inotify_insert_file(char * name, const char * path)
|
||||
/* Is it cover art for another file? */
|
||||
if( is_image(path) )
|
||||
update_if_album_art(path);
|
||||
else if( ends_with(path, ".srt") )
|
||||
check_for_captions(path, 0);
|
||||
|
||||
/* Check if we're supposed to be scanning for this file type in this directory */
|
||||
while( media_path )
|
||||
|
50
metadata.c
50
metadata.c
@ -118,6 +118,55 @@ get_fourcc(const char *s)
|
||||
return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24);
|
||||
}
|
||||
|
||||
void
|
||||
check_for_captions(const char * path, sqlite_int64 detailID)
|
||||
{
|
||||
char * sql;
|
||||
char * file = malloc(PATH_MAX);
|
||||
char **result;
|
||||
int ret, rows;
|
||||
|
||||
sprintf(file, "%s", path);
|
||||
strip_ext(file);
|
||||
|
||||
/* If we weren't given a detail ID, look for one. */
|
||||
if( !detailID )
|
||||
{
|
||||
sql = sqlite3_mprintf("SELECT ID from DETAILS where PATH glob '%q.*'"
|
||||
" and MIME glob 'video/*' limit 1", file);
|
||||
ret = sql_get_table(db, sql, &result, &rows, NULL);
|
||||
if( ret == SQLITE_OK )
|
||||
{
|
||||
if( rows )
|
||||
{
|
||||
detailID = strtoll(result[1], NULL, 10);
|
||||
//DEBUG DPRINTF(E_DEBUG, L_METADATA, "New file %s looks like a caption file.\n", path);
|
||||
}
|
||||
/*else
|
||||
{
|
||||
DPRINTF(E_DEBUG, L_METADATA, "No file found for caption %s.\n", path);
|
||||
}*/
|
||||
sqlite3_free_table(result);
|
||||
}
|
||||
sqlite3_free(sql);
|
||||
if( !detailID )
|
||||
goto no_source_video;
|
||||
}
|
||||
|
||||
strcat(file, ".srt");
|
||||
if( access(file, R_OK) == 0 )
|
||||
{
|
||||
sql = sqlite3_mprintf("INSERT into CAPTIONS"
|
||||
" (ID, PATH) "
|
||||
"VALUES"
|
||||
" (%lld, %Q)", detailID, file);
|
||||
sql_exec(db, sql);
|
||||
sqlite3_free(sql);
|
||||
}
|
||||
no_source_video:
|
||||
free(file);
|
||||
}
|
||||
|
||||
sqlite_int64
|
||||
GetFolderMetadata(const char * name, const char * path, const char * artist, const char * genre, const char * album_art)
|
||||
{
|
||||
@ -942,6 +991,7 @@ GetVideoMetadata(const char * path, char * name)
|
||||
else
|
||||
{
|
||||
ret = sqlite3_last_insert_rowid(db);
|
||||
check_for_captions(path, ret);
|
||||
}
|
||||
sqlite3_free(sql);
|
||||
if( m.dlna_pn )
|
||||
|
@ -73,6 +73,9 @@ ends_with(const char * haystack, const char * needle);
|
||||
char *
|
||||
modifyString(char * string, const char * before, const char * after, short like);
|
||||
|
||||
void
|
||||
check_for_captions(const char * path, sqlite_int64 detailID);
|
||||
|
||||
sqlite_int64
|
||||
GetFolderMetadata(const char * name, const char * path, const char * artist, const char * genre, const char * album_art);
|
||||
|
||||
|
@ -638,6 +638,12 @@ CreateDatabase(void)
|
||||
")");
|
||||
if( ret != SQLITE_OK )
|
||||
goto sql_failed;
|
||||
ret = sql_exec(db, "CREATE TABLE CAPTIONS ("
|
||||
"ID INTEGER PRIMARY KEY, "
|
||||
"PATH TEXT NOT NULL"
|
||||
")");
|
||||
if( ret != SQLITE_OK )
|
||||
goto sql_failed;
|
||||
ret = sql_exec(db, "CREATE TABLE SETTINGS ("
|
||||
"UPDATE_ID INTEGER PRIMARY KEY DEFAULT 0"
|
||||
")");
|
||||
|
84
upnphttp.c
84
upnphttp.c
@ -337,6 +337,10 @@ intervening space) by either an integer or the keyword "infinite". */
|
||||
h->reqflags |= FLAG_XFERBACKGROUND;
|
||||
}
|
||||
}
|
||||
else if(strncasecmp(line, "getCaptionInfo.sec", 18)==0)
|
||||
{
|
||||
h->reqflags |= FLAG_CAPTION;
|
||||
}
|
||||
}
|
||||
next_header:
|
||||
while(!(line[0] == '\r' && line[1] == '\n'))
|
||||
@ -791,6 +795,11 @@ ProcessHttpQuery_upnphttp(struct upnphttp * h)
|
||||
SendResp_icon(h, HttpUrl+7);
|
||||
CloseSocket_upnphttp(h);
|
||||
}
|
||||
else if(strncmp(HttpUrl, "/Captions/", 10) == 0)
|
||||
{
|
||||
SendResp_caption(h, HttpUrl+10);
|
||||
CloseSocket_upnphttp(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_WARN, L_HTTP, "%s not found, responding ERROR 404\n", HttpUrl);
|
||||
@ -1119,7 +1128,6 @@ SendResp_icon(struct upnphttp * h, char * icon)
|
||||
free(header);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SendResp_albumArt(struct upnphttp * h, char * object)
|
||||
{
|
||||
@ -1199,6 +1207,64 @@ SendResp_albumArt(struct upnphttp * h, char * object)
|
||||
sqlite3_free_table(result);
|
||||
}
|
||||
|
||||
void
|
||||
SendResp_caption(struct upnphttp * h, char * object)
|
||||
{
|
||||
char header[1500];
|
||||
char sql_buf[256];
|
||||
char **result;
|
||||
int rows = 0;
|
||||
char *path;
|
||||
char date[30];
|
||||
time_t curtime = time(NULL);
|
||||
off_t offset = 0, size;
|
||||
int sendfh;
|
||||
|
||||
memset(header, 0, 1500);
|
||||
|
||||
strip_ext(object);
|
||||
sprintf(sql_buf, "SELECT PATH from CAPTIONS where ID = %s", object);
|
||||
sql_get_table(db, sql_buf, &result, &rows, NULL);
|
||||
if( !rows )
|
||||
{
|
||||
DPRINTF(E_WARN, L_HTTP, "CAPTION ID %s not found, responding ERROR 404\n", object);
|
||||
Send404(h);
|
||||
goto error;
|
||||
}
|
||||
path = result[1];
|
||||
DPRINTF(E_INFO, L_HTTP, "Serving caption ID: %s [%s]\n", object, path);
|
||||
|
||||
if( access(path, F_OK) != 0 )
|
||||
goto error;
|
||||
|
||||
strftime(date, 30,"%a, %d %b %Y %H:%M:%S GMT" , gmtime(&curtime));
|
||||
sendfh = open(path, O_RDONLY);
|
||||
if( sendfh < 0 ) {
|
||||
DPRINTF(E_ERROR, L_HTTP, "Error opening %s\n", path);
|
||||
goto error;
|
||||
}
|
||||
size = lseek(sendfh, 0, SEEK_END);
|
||||
lseek(sendfh, 0, SEEK_SET);
|
||||
|
||||
sprintf(header, "HTTP/1.1 200 OK\r\n"
|
||||
"Content-Type: smi/caption\r\n"
|
||||
"Content-Length: %jd\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
"EXT:\r\n"
|
||||
"Server: " MINIDLNA_SERVER_STRING "\r\n\r\n",
|
||||
size, date);
|
||||
|
||||
if( (send_data(h, header, strlen(header)) == 0) && (h->req_command != EHead) && (sendfh > 0) )
|
||||
{
|
||||
send_file(h, sendfh, offset, size);
|
||||
}
|
||||
close(sendfh);
|
||||
|
||||
error:
|
||||
sqlite3_free_table(result);
|
||||
}
|
||||
|
||||
void
|
||||
SendResp_thumbnail(struct upnphttp * h, char * object)
|
||||
{
|
||||
@ -1631,6 +1697,22 @@ SendResp_dlnafile(struct upnphttp * h, char * object)
|
||||
}
|
||||
}
|
||||
|
||||
if( h->reqflags & FLAG_CAPTION )
|
||||
{
|
||||
sprintf(sql_buf, "SELECT 1 from CAPTIONS where ID = '%lld'", id);
|
||||
ret = sql_get_table(db, sql_buf, &result, &rows, NULL);
|
||||
if( ret == SQLITE_OK )
|
||||
{
|
||||
if( rows )
|
||||
{
|
||||
sprintf(hdr_buf, "CaptionInfo.sec: http://%s:%d/Captions/%lld.srt\r\n",
|
||||
lan_addr[0].str, runtime_vars.port, id);
|
||||
strcat(header, hdr_buf);
|
||||
}
|
||||
sqlite3_free_table(result);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(hdr_buf, "Accept-Ranges: bytes\r\n"
|
||||
"Connection: close\r\n"
|
||||
"Date: %s\r\n"
|
||||
|
@ -80,6 +80,7 @@ struct upnphttp {
|
||||
#define FLAG_XFERSTREAMING 0x00001000
|
||||
#define FLAG_XFERINTERACTIVE 0x00002000
|
||||
#define FLAG_XFERBACKGROUND 0x00004000
|
||||
#define FLAG_CAPTION 0x00008000
|
||||
|
||||
#define FLAG_DLNA 0x00100000
|
||||
#define FLAG_MIME_AVI_DIVX 0x00200000
|
||||
@ -136,6 +137,8 @@ SendResp_icon(struct upnphttp *, char * url);
|
||||
void
|
||||
SendResp_albumArt(struct upnphttp *, char * url);
|
||||
void
|
||||
SendResp_caption(struct upnphttp *, char * url);
|
||||
void
|
||||
SendResp_resizedimg(struct upnphttp *, char * url);
|
||||
void
|
||||
SendResp_thumbnail(struct upnphttp *, char * url);
|
||||
|
Loading…
x
Reference in New Issue
Block a user