media-export: Support videos without audio
[profile/ivi/rygel.git] / src / plugins / media-export / rygel-media-export-item.vala
1 /*
2  * Copyright (C) 2008 Zeeshan Ali <zeenix@gmail.com>.
3  * Copyright (C) 2008 Nokia Corporation.
4  *
5  * Author: Zeeshan Ali <zeenix@gmail.com>
6  *
7  * This file is part of Rygel.
8  *
9  * Rygel is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser 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.
13  *
14  * Rygel 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 Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24 using GUPnP;
25 using Gst;
26
27 /**
28  * Represents MediaExport item.
29  */
30 namespace Rygel.MediaExport.ItemFactory {
31     public static MediaItem create_simple (MediaContainer parent,
32                                            File           file,
33                                            string         mime,
34                                            uint64         size,
35                                            uint64         mtime) {
36         var title = file.get_basename ();
37         MediaItem item;
38
39         if (mime.has_prefix ("video/")) {
40             item = new VideoItem (MediaCache.get_id (file), parent, title);
41         } else if (mime.has_prefix ("image/")) {
42             item = new PhotoItem (MediaCache.get_id (file), parent, title);
43         } else {
44             item = new MusicItem (MediaCache.get_id (file), parent, title);
45         }
46
47         item.mime_type = mime;
48         item.size = (int64) size;
49         item.modified = mtime;
50         item.add_uri (file.get_uri ());
51
52         return item;
53     }
54
55     public static MediaItem? create_from_info (MediaContainer        parent,
56                                                File                  file,
57                                                GUPnP.DLNAInformation dlna_info,
58                                                string                mime,
59                                                uint64                size,
60                                                uint64                mtime) {
61         MediaItem item;
62         string id = MediaCache.get_id (file);
63         GLib.List<DiscovererAudioInfo> audio_streams;
64         GLib.List<DiscovererVideoInfo> video_streams;
65
66         audio_streams = dlna_info.info.get_audio_streams ();
67         video_streams = dlna_info.info.get_video_streams ();
68
69         if (audio_streams == null && video_streams == null) {
70             debug ("%s had neither audio nor video/picture " +
71                    "streams. Ignoring.",
72                    file.get_uri ());
73
74             return null;
75         }
76
77         if (audio_streams == null && video_streams.data.is_image()) {
78             item = new PhotoItem (id, parent, "");
79             return fill_photo_item (item as PhotoItem,
80                                     file,
81                                     dlna_info,
82                                     video_streams.data,
83                                     mime,
84                                     size,
85                                     mtime);
86         } else if (video_streams != null) {
87             item = new VideoItem (id, parent, "");
88
89             var audio_info = null as DiscovererAudioInfo;
90             if (audio_streams != null) {
91                 audio_info = audio_streams.data;
92             }
93
94             return fill_video_item (item as VideoItem,
95                                     file,
96                                     dlna_info,
97                                     video_streams.data,
98                                     audio_info,
99                                     mime,
100                                     size,
101                                     mtime);
102         } else if (audio_streams != null) {
103             item = new MusicItem (id, parent, "");
104             return fill_music_item (item as MusicItem,
105                                     file,
106                                     dlna_info,
107                                     audio_streams.data,
108                                     mime,
109                                     size,
110                                     mtime);
111         } else {
112             return null;
113         }
114     }
115
116     private static void fill_audio_item (AudioItem            item,
117                                          DLNAInformation      dlna_info,
118                                          DiscovererAudioInfo? audio_info) {
119         if (dlna_info.info.get_duration () > 0) {
120             item.duration = (long) (dlna_info.info.get_duration () / Gst.SECOND);
121         } else {
122             item.duration = -1;
123         }
124
125         if (audio_info != null) {
126             if (audio_info.get_tags () != null) {
127                 uint tmp;
128                 audio_info.get_tags ().get_uint (TAG_BITRATE, out tmp);
129                 item.bitrate = (int) tmp / 8;
130             }
131             item.channels = (int) audio_info.get_channels ();
132             item.sample_freq = (int) audio_info.get_sample_rate ();
133         }
134     }
135
136
137     private static MediaItem fill_video_item (VideoItem            item,
138                                                 File                 file,
139                                               DLNAInformation      dlna_info,
140                                               DiscovererVideoInfo  video_info,
141                                               DiscovererAudioInfo? audio_info,
142                                               string               mime,
143                                               uint64               size,
144                                               uint64               mtime) {
145         fill_audio_item (item as AudioItem, dlna_info, audio_info);
146         fill_media_item (item, file, dlna_info, mime, size, mtime);
147
148         item.width = (int) video_info.get_width ();
149         item.height = (int) video_info.get_height ();
150         item.color_depth = (int) video_info.get_depth ();
151
152         return item;
153     }
154
155     private static MediaItem fill_photo_item (PhotoItem           item,
156                                               File                file,
157                                               DLNAInformation     dlna_info,
158                                               DiscovererVideoInfo video_info,
159                                               string              mime,
160                                               uint64              size,
161                                               uint64              mtime) {
162         fill_media_item (item, file, dlna_info, mime, size, mtime);
163
164         item.width = (int) video_info.get_width ();
165         item.height = (int) video_info.get_height ();
166         item.color_depth = (int) video_info.get_depth ();
167
168         return item;
169     }
170
171     private static MediaItem fill_music_item (MusicItem            item,
172                                               File                 file,
173                                               DLNAInformation      dlna_info,
174                                               DiscovererAudioInfo? audio_info,
175                                               string               mime,
176                                               uint64               size,
177                                               uint64               mtime) {
178         fill_audio_item (item as AudioItem, dlna_info, audio_info);
179         fill_media_item (item, file, dlna_info, mime, size, mtime);
180
181         if (audio_info != null) {
182             if (audio_info.get_tags () != null) {
183                 unowned Gst.Buffer buffer;
184                 audio_info.get_tags ().get_buffer (TAG_IMAGE, out buffer);
185                 if (buffer != null) {
186                     var structure = buffer.caps.get_structure (0);
187                     int image_type;
188                     structure.get_enum ("image-type",
189                             typeof (Gst.TagImageType),
190                             out image_type);
191                     switch (image_type) {
192                         case TagImageType.UNDEFINED:
193                         case TagImageType.FRONT_COVER:
194                             var store = MediaArtStore.get_default ();
195                             var thumb = store.get_media_art_file ("album",
196                                     item,
197                                     true);
198                             try {
199                                 var writer = new JPEGWriter ();
200                                 writer.write (buffer, thumb);
201                             } catch (Error error) {}
202                             break;
203                         default:
204                             break;
205                     }
206                 }
207             }
208             dlna_info.info.get_tags ().get_string (TAG_ARTIST, out item.artist);
209             dlna_info.info.get_tags ().get_string (TAG_ALBUM, out item.album);
210             dlna_info.info.get_tags ().get_string (TAG_GENRE, out item.genre);
211
212             uint tmp;
213             dlna_info.info.get_tags() .get_uint (TAG_TRACK_NUMBER, out tmp);
214             item.track_number = (int) tmp;
215         }
216
217         return item;
218     }
219
220     private static void fill_media_item (MediaItem       item,
221                                   File                   file,
222                                   DLNAInformation dlna_info,
223                                   string           mime,
224                                   uint64           size,
225                                   uint64           mtime) {
226         string title = null;
227
228         if (dlna_info.info.get_tags () == null ||
229             !dlna_info.info.get_tags ().get_string (TAG_TITLE, out title)) {
230             title = file.get_basename ();
231         }
232
233         item.title = title;
234
235         if (dlna_info.info.get_tags () != null) {
236             GLib.Date? date;
237             if (dlna_info.info.get_tags ().get_date (TAG_DATE, out date)) {
238                 char[] datestr = new char[30];
239                 date.strftime (datestr, "%F");
240                 item.date = (string) datestr;
241             }
242         }
243
244         // use mtime if no time tag was available
245         if (item.date == null) {
246             TimeVal tv = { (long) mtime, 0 };
247             item.date = tv.to_iso8601 ();
248         }
249
250         item.size = (int64) size;
251         item.modified = (int64) mtime;
252
253         if (dlna_info.name != null) {
254             item.dlna_profile = dlna_info.name;
255             item.mime_type = dlna_info.mime;
256         } else {
257             item.mime_type = mime;
258         }
259
260         item.add_uri (file.get_uri ());
261     }
262 }
263