* Add SRT subtitle support using Samsung's method.

This commit is contained in:
Justin Maggard 2009-10-15 00:40:27 +00:00
parent 4efa9d06ac
commit f7e525019a
6 changed files with 148 additions and 1 deletions

View File

@ -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 )

View File

@ -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 )

View File

@ -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);

View File

@ -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"
")");

View File

@ -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"

View File

@ -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);