* Add the ability to change the root media container. (Thanks to Ivan Mironov)
This commit is contained in:
parent
f6e3e0e8c1
commit
108fda1e84
5
NEWS
5
NEWS
@ -1,3 +1,8 @@
|
|||||||
|
1.0.21 - Released 00-MONTH-2011
|
||||||
|
--------------------------------
|
||||||
|
- Add the ability to change the root media container.
|
||||||
|
- Add WAV/RIFF INFO tag parsing support for the most common tags.
|
||||||
|
|
||||||
1.0.20 - Released 09-June-2011
|
1.0.20 - Released 09-June-2011
|
||||||
--------------------------------
|
--------------------------------
|
||||||
- Fix a crash bug when scanning MPEG-TS files with odd packet sizes.
|
- Fix a crash bug when scanning MPEG-TS files with odd packet sizes.
|
||||||
|
29
minidlna.c
29
minidlna.c
@ -376,6 +376,7 @@ init(int argc, char * * argv)
|
|||||||
|
|
||||||
runtime_vars.port = -1;
|
runtime_vars.port = -1;
|
||||||
runtime_vars.notify_interval = 895; /* seconds between SSDP announces */
|
runtime_vars.notify_interval = 895; /* seconds between SSDP announces */
|
||||||
|
runtime_vars.root_container = NULL;
|
||||||
|
|
||||||
/* read options file first since
|
/* read options file first since
|
||||||
* command line arguments have final say */
|
* command line arguments have final say */
|
||||||
@ -559,6 +560,34 @@ init(int argc, char * * argv)
|
|||||||
if( (strcmp(ary_options[i].value, "yes") == 0) || atoi(ary_options[i].value) )
|
if( (strcmp(ary_options[i].value, "yes") == 0) || atoi(ary_options[i].value) )
|
||||||
SETFLAG(DLNA_STRICT_MASK);
|
SETFLAG(DLNA_STRICT_MASK);
|
||||||
break;
|
break;
|
||||||
|
case ROOT_CONTAINER:
|
||||||
|
switch( ary_options[i].value[0] )
|
||||||
|
{
|
||||||
|
case '.':
|
||||||
|
runtime_vars.root_container = NULL;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
case 'b':
|
||||||
|
runtime_vars.root_container = BROWSEDIR_ID;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
case 'm':
|
||||||
|
runtime_vars.root_container = MUSIC_ID;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
case 'v':
|
||||||
|
runtime_vars.root_container = VIDEO_ID;
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
case 'p':
|
||||||
|
runtime_vars.root_container = IMAGE_ID;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Invalid root container! [%s]\n",
|
||||||
|
ary_options[i].value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unknown option in file %s\n",
|
fprintf(stderr, "Unknown option in file %s\n",
|
||||||
optionsfile);
|
optionsfile);
|
||||||
|
@ -48,3 +48,13 @@ notify_interval=900
|
|||||||
# in its XML description
|
# in its XML description
|
||||||
serial=12345678
|
serial=12345678
|
||||||
model_number=1
|
model_number=1
|
||||||
|
|
||||||
|
# use different container as root of the tree
|
||||||
|
# possible values:
|
||||||
|
# + "." - use standard container (this is the default)
|
||||||
|
# + "B" - "Browse Directory"
|
||||||
|
# + "M" - "Music"
|
||||||
|
# + "V" - "Video"
|
||||||
|
# + "P" - "Pictures"
|
||||||
|
# if you specify "B" and client device is audio-only then "Music/Folders" will be used as root
|
||||||
|
#root_container=.
|
||||||
|
@ -42,6 +42,7 @@ struct lan_addr_s {
|
|||||||
struct runtime_vars_s {
|
struct runtime_vars_s {
|
||||||
int port; /* HTTP Port */
|
int port; /* HTTP Port */
|
||||||
int notify_interval; /* seconds between SSDP announces */
|
int notify_interval; /* seconds between SSDP announces */
|
||||||
|
char *root_container; /* root ObjectID (instead of "0") */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct string_s {
|
struct string_s {
|
||||||
|
@ -59,7 +59,8 @@ static const struct {
|
|||||||
{ UPNPDBDIR, "db_dir" },
|
{ UPNPDBDIR, "db_dir" },
|
||||||
{ UPNPLOGDIR, "log_dir" },
|
{ UPNPLOGDIR, "log_dir" },
|
||||||
{ ENABLE_TIVO, "enable_tivo" },
|
{ ENABLE_TIVO, "enable_tivo" },
|
||||||
{ ENABLE_DLNA_STRICT, "strict_dlna" }
|
{ ENABLE_DLNA_STRICT, "strict_dlna" },
|
||||||
|
{ ROOT_CONTAINER, "root_container" }
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -52,7 +52,8 @@ enum upnpconfigoptions {
|
|||||||
UPNPDBDIR, /* base directory to store the database and album art cache */
|
UPNPDBDIR, /* base directory to store the database and album art cache */
|
||||||
UPNPLOGDIR, /* base directory to store the log file */
|
UPNPLOGDIR, /* base directory to store the log file */
|
||||||
ENABLE_TIVO, /* enable support for streaming images and music to TiVo */
|
ENABLE_TIVO, /* enable support for streaming images and music to TiVo */
|
||||||
ENABLE_DLNA_STRICT /* strictly adhere to DLNA specs */
|
ENABLE_DLNA_STRICT, /* strictly adhere to DLNA specs */
|
||||||
|
ROOT_CONTAINER /* root ObjectID (instead of "0") */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* readoptionsfile()
|
/* readoptionsfile()
|
||||||
|
@ -115,6 +115,7 @@ struct upnphttp {
|
|||||||
#define FLAG_AUDIO_ONLY 0x08000000
|
#define FLAG_AUDIO_ONLY 0x08000000
|
||||||
|
|
||||||
#define FLAG_FREE_OBJECT_ID 0x00000001
|
#define FLAG_FREE_OBJECT_ID 0x00000001
|
||||||
|
#define FLAG_ROOT_CONTAINER 0x00000002
|
||||||
|
|
||||||
/* New_upnphttp() */
|
/* New_upnphttp() */
|
||||||
struct upnphttp *
|
struct upnphttp *
|
||||||
|
36
upnpsoap.c
36
upnpsoap.c
@ -609,10 +609,11 @@ add_res(char *size, char *duration, char *bitrate, char *sampleFrequency,
|
|||||||
runtime_vars.port, detailID, ext);
|
runtime_vars.port, detailID, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SELECT_COLUMNS "SELECT o.OBJECT_ID, o.PARENT_ID, o.REF_ID, o.DETAIL_ID, o.CLASS," \
|
#define COLUMNS "o.REF_ID, o.DETAIL_ID, o.CLASS," \
|
||||||
" d.SIZE, d.TITLE, d.DURATION, d.BITRATE, d.SAMPLERATE, d.ARTIST," \
|
" d.SIZE, d.TITLE, d.DURATION, d.BITRATE, d.SAMPLERATE, d.ARTIST," \
|
||||||
" d.ALBUM, d.GENRE, d.COMMENT, d.CHANNELS, d.TRACK, d.DATE, d.RESOLUTION," \
|
" d.ALBUM, d.GENRE, d.COMMENT, d.CHANNELS, d.TRACK, d.DATE, d.RESOLUTION," \
|
||||||
" d.THUMBNAIL, d.CREATOR, d.DLNA_PN, d.MIME, d.ALBUM_ART, d.DISC "
|
" d.THUMBNAIL, d.CREATOR, d.DLNA_PN, d.MIME, d.ALBUM_ART, d.DISC "
|
||||||
|
#define SELECT_COLUMNS "SELECT o.OBJECT_ID, o.PARENT_ID, " COLUMNS
|
||||||
|
|
||||||
static int
|
static int
|
||||||
callback(void *args, int argc, char **argv, char **azColName)
|
callback(void *args, int argc, char **argv, char **azColName)
|
||||||
@ -664,6 +665,9 @@ callback(void *args, int argc, char **argv, char **azColName)
|
|||||||
else
|
else
|
||||||
strcpy(dlna_buf, "*");
|
strcpy(dlna_buf, "*");
|
||||||
|
|
||||||
|
if( runtime_vars.root_container && strcmp(parent, runtime_vars.root_container) == 0 )
|
||||||
|
parent = "0";
|
||||||
|
|
||||||
if( strncmp(class, "item", 4) == 0 )
|
if( strncmp(class, "item", 4) == 0 )
|
||||||
{
|
{
|
||||||
/* We may need special handling for certain MIME types */
|
/* We may need special handling for certain MIME types */
|
||||||
@ -1029,19 +1033,31 @@ BrowseContentDirectory(struct upnphttp * h, const char * action)
|
|||||||
ObjectID, RequestedCount, StartingIndex,
|
ObjectID, RequestedCount, StartingIndex,
|
||||||
BrowseFlag, Filter, SortCriteria);
|
BrowseFlag, Filter, SortCriteria);
|
||||||
|
|
||||||
if( (args.flags & FLAG_AUDIO_ONLY) && (strcmp(ObjectID, "0") == 0) )
|
if( strcmp(ObjectID, "0") == 0 )
|
||||||
{
|
{
|
||||||
ObjectID = sqlite3_mprintf("%s", MUSIC_ID);
|
args.flags |= FLAG_ROOT_CONTAINER;
|
||||||
args.flags |= FLAG_FREE_OBJECT_ID;
|
if( runtime_vars.root_container )
|
||||||
|
{
|
||||||
|
if( (args.flags & FLAG_AUDIO_ONLY) && (strcmp(runtime_vars.root_container, BROWSEDIR_ID) == 0) )
|
||||||
|
ObjectID = MUSIC_DIR_ID;
|
||||||
|
else
|
||||||
|
ObjectID = runtime_vars.root_container;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( args.flags & FLAG_AUDIO_ONLY )
|
||||||
|
ObjectID = MUSIC_ID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( strcmp(BrowseFlag+6, "Metadata") == 0 )
|
if( strcmp(BrowseFlag+6, "Metadata") == 0 )
|
||||||
{
|
{
|
||||||
args.requested = 1;
|
args.requested = 1;
|
||||||
sql = sqlite3_mprintf( SELECT_COLUMNS
|
sql = sqlite3_mprintf("SELECT %s, " COLUMNS
|
||||||
"from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)"
|
"from OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)"
|
||||||
" where OBJECT_ID = '%s';"
|
" where OBJECT_ID = '%s';",
|
||||||
, ObjectID);
|
(args.flags & FLAG_ROOT_CONTAINER) ? "0, -1" : "o.OBJECT_ID, o.PARENT_ID",
|
||||||
|
ObjectID);
|
||||||
ret = sqlite3_exec(db, sql, callback, (void *) &args, &zErrMsg);
|
ret = sqlite3_exec(db, sql, callback, (void *) &args, &zErrMsg);
|
||||||
totalMatches = args.returned;
|
totalMatches = args.returned;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user