1 //=========================================================================
2 // FILENAME : playlist.c
3 // DESCRIPTION : Playlist
4 //=========================================================================
5 // Copyright (c) 2008- NETGEAR, Inc. All Rights Reserved.
6 //=========================================================================
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
34 static int _utf8bom
= 0;
37 static int (*_next_track
)(struct song_metadata
*, struct stat
*, char*, char*);
38 static int _m3u_pls_next_track(struct song_metadata
*, struct stat
*, char*, char*);
41 start_plist(const char *path
, struct song_metadata
*psong
, struct stat
*stat
, char *lang
, char *type
)
49 if(strcasecmp(type
, "m3u") == 0)
50 _next_track
= _m3u_pls_next_track
;
51 else if(strcasecmp(type
, "pls") == 0)
52 _next_track
= _m3u_pls_next_track
;
56 DPRINTF(E_ERROR
, L_SCANNER
, "Unsupported playlist type <%s> (%s)\n", type
, path
);
60 if(!(fp
= fopen(path
, "rb")))
62 DPRINTF(E_ERROR
, L_SCANNER
, "Cannot open %s\n", path
);
69 memset((void*)psong
, 0, sizeof(struct song_metadata
));
71 psong
->path
= strdup(path
);
74 fname
= strrchr(psong
->path
, '/');
75 psong
->basename
= fname
? fname
+ 1 : psong
->path
;
77 psong
->title
= strdup(psong
->basename
);
78 suffix
= strrchr(psong
->title
, '.');
79 if(suffix
) *suffix
= '\0';
83 if(!psong
->time_modified
)
84 psong
->time_modified
= stat
->st_mtime
;
85 psong
->file_size
= stat
->st_size
;
92 _m3u_pls_next_track(struct song_metadata
*psong
, struct stat
*stat
, char *lang
, char *type
)
94 char buf
[MAX_BUF
], *p
;
97 memset((void*)psong
, 0, sizeof(struct song_metadata
));
100 p
= fgets(buf
, MAX_BUF
, fp
);
107 if(strcasecmp(type
, "m3u") == 0)
110 if(!_utf8bom
&& p
[0] == '\xef' && p
[1] == '\xbb' && p
[2] == '\xbf')
119 while(isspace(*p
)) p
++;
121 if(!(*p
) || *p
== '#')
126 DPRINTF(E_ERROR
, L_SCANNER
, "Playlist looks bad (unprintable characters)\n");
131 if(strcasecmp(type
, "pls") == 0)
133 // verify that it's a valid pls playlist
136 if(strncmp(p
, "[playlist]", 10))
142 if(strncmp(p
, "File", 4) != 0)
145 psong
->track
= strtol(p
+4, &p
, 10);
146 if(!psong
->track
|| !p
++)
148 _trackno
= psong
->track
;
150 else if(strcasecmp(type
, "m3u") == 0)
151 psong
->track
= ++_trackno
;
154 while(p
[len
-1] == '\r' || p
[len
-1] == '\n')
156 psong
->path
= strdup(p
);
159 p
= fgets(buf
, MAX_BUF
, fp
);
167 next_plist_track(struct song_metadata
*psong
, struct stat
*stat
, char *lang
, char *type
)
170 return _next_track(psong
, stat
, lang
, type
);