comparison src/Container/m3u/m3u.c @ 0:13389e613d67 trunk

[svn] - initial import of audacious-plugins tree (lots to do)
author nenolod
date Mon, 18 Sep 2006 01:11:49 -0700
parents
children 088092a52fea
comparison
equal deleted inserted replaced
-1:000000000000 0:13389e613d67
1 /*
2 * Audacious: A cross-platform multimedia player
3 * Copyright (c) 2006 William Pitcock, Tony Vroon, George Averill,
4 * Giacomo Lozito, Derek Pomery and Yoshiki Yazawa.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include <glib.h>
22 #include <string.h>
23 #include <glib.h>
24 #include <glib/gprintf.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>
28
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/errno.h>
33
34 #include "libaudacious/vfs.h"
35 #include "audacious/main.h"
36 #include "audacious/util.h"
37 #include "audacious/playlist.h"
38 #include "audacious/playlist_container.h"
39 #include "audacious/plugin.h"
40
41 static void
42 parse_extm3u_info(const gchar * info, gchar ** title, gint * length)
43 {
44 gchar *str;
45
46 g_return_if_fail(info != NULL);
47 g_return_if_fail(title != NULL);
48 g_return_if_fail(length != NULL);
49
50 *title = NULL;
51 *length = -1;
52
53 if (!str_has_prefix_nocase(info, "#EXTINF:")) {
54 g_message("Invalid m3u metadata (%s)", info);
55 return;
56 }
57
58 info += 8;
59
60 *length = atoi(info);
61 if (*length <= 0)
62 *length = -1;
63 else
64 *length *= 1000;
65
66 if ((str = strchr(info, ','))) {
67 *title = g_strstrip(g_strdup(str + 1));
68 if (strlen(*title) < 1) {
69 g_free(*title);
70 *title = NULL;
71 }
72 }
73 }
74
75 static void
76 playlist_load_m3u(const gchar * filename, gint pos)
77 {
78 VFSFile *file;
79 gchar *line;
80 gchar *ext_info = NULL, *ext_title = NULL;
81 gsize line_len = 1024;
82 gint ext_len = -1;
83 gboolean is_extm3u = FALSE;
84
85 if ((file = vfs_fopen(filename, "rb")) == NULL)
86 return;
87
88 line = g_malloc(line_len);
89 while (vfs_fgets(line, line_len, file)) {
90 while (strlen(line) == line_len - 1 && line[strlen(line) - 1] != '\n') {
91 line_len += 1024;
92 line = g_realloc(line, line_len);
93 vfs_fgets(&line[strlen(line)], 1024, file);
94 }
95
96 while (line[strlen(line) - 1] == '\r' ||
97 line[strlen(line) - 1] == '\n')
98 line[strlen(line) - 1] = '\0';
99
100 if (str_has_prefix_nocase(line, "#EXTM3U")) {
101 is_extm3u = TRUE;
102 continue;
103 }
104
105 if (is_extm3u && str_has_prefix_nocase(line, "#EXTINF:")) {
106 str_replace_in(&ext_info, g_strdup(line));
107 continue;
108 }
109
110 if (line[0] == '#' || strlen(line) == 0) {
111 if (ext_info) {
112 g_free(ext_info);
113 ext_info = NULL;
114 }
115 continue;
116 }
117
118 if (is_extm3u) {
119 if (cfg.use_pl_metadata && ext_info)
120 parse_extm3u_info(ext_info, &ext_title, &ext_len);
121 g_free(ext_info);
122 ext_info = NULL;
123 }
124
125 playlist_load_ins_file(line, filename, pos, ext_title, ext_len);
126
127 str_replace_in(&ext_title, NULL);
128 ext_len = -1;
129
130 if (pos >= 0)
131 pos++;
132 }
133
134 vfs_fclose(file);
135 g_free(line);
136 }
137
138 static void
139 playlist_save_m3u(const gchar *filename, gint pos)
140 {
141 GList *node;
142 gchar *outstr = NULL;
143 VFSFile *file;
144
145 g_return_if_fail(filename != NULL);
146
147 file = vfs_fopen(filename, "wb");
148
149 g_return_if_fail(file != NULL);
150
151 if (cfg.use_pl_metadata)
152 vfs_fprintf(file, "#EXTM3U\n");
153
154 PLAYLIST_LOCK();
155
156 for (node = playlist_get(); node; node = g_list_next(node)) {
157 PlaylistEntry *entry = PLAYLIST_ENTRY(node->data);
158
159 if (entry->title && cfg.use_pl_metadata) {
160 gint seconds;
161
162 if (entry->length > 0)
163 seconds = (entry->length) / 1000;
164 else
165 seconds = -1;
166
167 outstr = g_locale_from_utf8(entry->title, -1, NULL, NULL, NULL);
168 if(outstr) {
169 vfs_fprintf(file, "#EXTINF:%d,%s\n", seconds, outstr);
170 g_free(outstr);
171 outstr = NULL;
172 } else {
173 vfs_fprintf(file, "#EXTINF:%d,%s\n", seconds, entry->title);
174 }
175 }
176
177 vfs_fprintf(file, "%s\n", entry->filename);
178 }
179
180 PLAYLIST_UNLOCK();
181
182 vfs_fclose(file);
183 }
184
185 PlaylistContainer plc_m3u = {
186 .name = "M3U Playlist Format",
187 .ext = "m3u",
188 .plc_read = playlist_load_m3u,
189 .plc_write = playlist_save_m3u,
190 };
191
192 static void init(void)
193 {
194 playlist_container_register(&plc_m3u);
195 }
196
197 static void cleanup(void)
198 {
199 playlist_container_unregister(&plc_m3u);
200 }
201
202 LowlevelPlugin llp_m3u = {
203 NULL,
204 NULL,
205 "M3U Playlist Format",
206 init,
207 cleanup,
208 };
209
210 LowlevelPlugin *get_lplugin_info(void)
211 {
212 return &llp_m3u;
213 }