Merge "[Player] Updated comments." into tizen
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Metadata / MetadataEditor / MetadataEditor.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18 using System;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Multimedia
22 {
23     static internal class MetadataEditorLog
24     {
25         internal const string LogTag = "Tizen.Multimedia.MetadataEditor";
26     }
27
28     /// <summary>
29     /// The Metadata editor class provides a set of functions to edit the metadata of the media file
30     /// </summary>
31     /// <privilege>
32     /// If you want to access only internal storage,
33     /// you should add privilege http://tizen.org/privilege/mediastorage. \n
34     /// Or if you want to access only external storage,
35     /// you should add privilege http://tizen.org/privilege/externalstorage. \n
36     /// </privilege>
37     public class MetadataEditor : IDisposable
38     {
39         private bool _disposed = false;
40         private IntPtr _handle = IntPtr.Zero;
41
42         private IntPtr MetadataHandle
43         {
44             get
45             {
46                 if (_handle == IntPtr.Zero)
47                 {
48                     throw new ObjectDisposedException(nameof(MetadataEditor));
49                 }
50
51                 return _handle;
52             }
53         }
54
55         /// <summary>
56         /// Initializes a new instance of the <see cref="MetadataEditor"/> class with the specified path.
57         /// </summary>
58         /// <since_tizen> 3 </since_tizen>
59         /// <param name="path"> The path of the media file to edit metadata </param>
60         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
61         /// <exception cref="NotSupportedException">The file is unsupported format.</exception>
62         /// <exception cref="System.IO.FileNotFoundException">The file does not exist.</exception>
63         public MetadataEditor(string path)
64         {
65             if (path == null)
66             {
67                 throw new ArgumentNullException(nameof(path));
68             }
69
70             MetadataEditorError ret = Interop.MetadataEditor.Create(out _handle);
71             MetadataEditorErrorFactory.ThrowIfError(ret, "Failed to create metadata");
72
73             try
74             {
75                 MetadataEditorErrorFactory.ThrowIfError(
76                     Interop.MetadataEditor.SetPath(MetadataHandle, path), "Failed to set path");
77             }
78             catch (Exception)
79             {
80                 Interop.MetadataEditor.Destroy(_handle);
81                 _handle = IntPtr.Zero;
82                 throw;
83             }
84         }
85
86         private string GetParam(MetadataEditorAttr attr)
87         {
88             IntPtr val = IntPtr.Zero;
89
90             try
91             {
92                 MetadataEditorError e = Interop.MetadataEditor.GetMetadata(MetadataHandle, attr, out val);
93                 MetadataEditorErrorFactory.ThrowIfError(e, "Failed to get metadata");
94
95                 return Marshal.PtrToStringAnsi(val);
96             }
97             finally
98             {
99                 Interop.Libc.Free(val);
100             }
101         }
102
103         private void SetParam(MetadataEditorAttr attr, string value)
104         {
105             MetadataEditorErrorFactory.ThrowIfError(
106                     Interop.MetadataEditor.SetMetadata(MetadataHandle, attr, value), "Fail to set value");
107         }
108
109         /// <summary>
110         /// Artist of media
111         /// </summary>
112         /// <since_tizen> 3 </since_tizen>
113         public string Artist
114         {
115             get
116             {
117                 return GetParam(MetadataEditorAttr.Artist);
118             }
119
120             set
121             {
122                 SetParam(MetadataEditorAttr.Artist, value);
123             }
124         }
125
126         /// <summary>
127         /// Title of media
128         /// </summary>
129         /// <since_tizen> 3 </since_tizen>
130         public string Title
131         {
132             get
133             {
134                 return GetParam(MetadataEditorAttr.Title);
135             }
136
137             set
138             {
139                 SetParam(MetadataEditorAttr.Title, value);
140             }
141         }
142
143         /// <summary>
144         /// Album name of media
145         /// </summary>
146         /// <since_tizen> 3 </since_tizen>
147         public string Album
148         {
149             get
150             {
151                 return GetParam(MetadataEditorAttr.Album);
152             }
153
154             set
155             {
156                 SetParam(MetadataEditorAttr.Album, value);
157             }
158         }
159
160         /// <summary>
161         /// Genre of media
162         /// </summary>
163         /// <since_tizen> 3 </since_tizen>
164         public string Genre
165         {
166             get
167             {
168                 return GetParam(MetadataEditorAttr.Genre);
169             }
170
171             set
172             {
173                 SetParam(MetadataEditorAttr.Genre, value);
174             }
175         }
176
177         /// <summary>
178         /// Author of media
179         /// </summary>
180         /// <since_tizen> 3 </since_tizen>
181         public string Author
182         {
183             get
184             {
185                 return GetParam(MetadataEditorAttr.Author);
186             }
187
188             set
189             {
190                 SetParam(MetadataEditorAttr.Author, value);
191             }
192         }
193
194         /// <summary>
195         /// Copyright of media
196         /// </summary>
197         /// <since_tizen> 3 </since_tizen>
198         public string Copyright
199         {
200             get
201             {
202                 return GetParam(MetadataEditorAttr.Copyright);
203             }
204
205             set
206             {
207                 SetParam(MetadataEditorAttr.Copyright, value);
208             }
209         }
210
211         /// <summary>
212         /// Date of media
213         /// </summary>
214         /// <since_tizen> 3 </since_tizen>
215         /// <remarks>
216         /// If the added media contains ID3 tag, This parameter refers to the recording time.
217         /// If the added media is a mp4 format, This parameter refers to the year.
218         /// </remarks>
219         public string Date
220         {
221             get
222             {
223                 return GetParam(MetadataEditorAttr.Date);
224             }
225
226             set
227             {
228                 SetParam(MetadataEditorAttr.Date, value);
229             }
230         }
231
232         /// <summary>
233         /// Description of media
234         /// </summary>
235         /// <since_tizen> 3 </since_tizen>
236         public string Description
237         {
238             get
239             {
240                 return GetParam(MetadataEditorAttr.Description);
241             }
242
243             set
244             {
245                 SetParam(MetadataEditorAttr.Description, value);
246             }
247         }
248
249         /// <summary>
250         /// Comment of media
251         /// </summary>
252         /// <since_tizen> 3 </since_tizen>
253         public string Comment
254         {
255             get
256             {
257                 return GetParam(MetadataEditorAttr.Comment);
258             }
259
260             set
261             {
262                 SetParam(MetadataEditorAttr.Comment, value);
263             }
264         }
265
266         /// <summary>
267         /// Track number of media
268         /// </summary>
269         /// <since_tizen> 3 </since_tizen>
270         public string TrackNumber
271         {
272             get
273             {
274                 return GetParam(MetadataEditorAttr.TrackNumber);
275             }
276
277             set
278             {
279                 SetParam(MetadataEditorAttr.TrackNumber, value);
280             }
281         }
282
283         /// <summary>
284         /// Album art count of media
285         /// </summary>
286         /// <since_tizen> 3 </since_tizen>
287         public string PictureCount
288         {
289             get
290             {
291                 return GetParam(MetadataEditorAttr.PictureCount);
292             }
293         }
294
295         /// <summary>
296         /// Conductor of media
297         /// </summary>
298         /// <since_tizen> 3 </since_tizen>
299         public string Conductor
300         {
301             get
302             {
303                 return GetParam(MetadataEditorAttr.Conductor);
304             }
305
306             set
307             {
308                 SetParam(MetadataEditorAttr.Conductor, value);
309             }
310         }
311
312         /// <summary>
313         /// Unsynchronized lyric of media
314         /// </summary>
315         /// <since_tizen> 3 </since_tizen>
316         public string UnsyncLyrics
317         {
318             get
319             {
320                 return GetParam(MetadataEditorAttr.UnsyncLyrics);
321             }
322
323             set
324             {
325                 SetParam(MetadataEditorAttr.UnsyncLyrics, value);
326             }
327         }
328
329         /// <summary>
330         /// Writes the modified metadata to a media file
331         /// </summary>
332         /// <since_tizen> 3 </since_tizen>
333         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
334         public void Commit()
335         {
336             MetadataEditorErrorFactory.ThrowIfError(
337                 Interop.MetadataEditor.UpdateMetadata(MetadataHandle), "Failed to update file");
338         }
339
340         /// <summary>
341         /// Gets the artwork image in a media file
342         /// </summary>
343         /// <since_tizen> 3 </since_tizen>
344         /// <param name="index"> Index of picture to import </param>
345         /// <returns> Artwork included in the media file</returns>
346         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
347         /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
348         public Artwork GetPicture(int index)
349         {
350             if (index < 0)
351             {
352                 throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
353             }
354
355             IntPtr data = IntPtr.Zero;
356             int size;
357             IntPtr mimeType = IntPtr.Zero;
358
359             try
360             {
361                 MetadataEditorErrorFactory.ThrowIfError(
362                     Interop.MetadataEditor.GetPicture(MetadataHandle, index, out data, out size, out mimeType), "Failed to get the value");
363
364                 if (size > 0)
365                 {
366                     byte[] tmpBuf = new byte[size];
367                     Marshal.Copy(data, tmpBuf, 0, size);
368
369                     return new Artwork(tmpBuf, Marshal.PtrToStringAnsi(mimeType));
370                 }
371
372                 return null;
373             }
374             finally
375             {
376                 if (data != IntPtr.Zero)
377                 {
378                     Interop.Libc.Free(data);
379                 }
380
381                 if (mimeType != IntPtr.Zero)
382                 {
383                     Interop.Libc.Free(mimeType);
384                 }
385             }
386         }
387
388         /// <summary>
389         /// Appends the picture to the media file.
390         /// </summary>
391         /// <since_tizen> 3 </since_tizen>
392         /// <param name="path">The path of picture for adding to the metadata.</param>
393         /// <exception cref="InvalidOperationException">Internal error occurs.</exception>
394         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
395         public void AddPicture(string path)
396         {
397             if (path == null)
398             {
399                 throw new ArgumentNullException(nameof(path));
400             }
401
402             MetadataEditorErrorFactory.ThrowIfError(
403                 Interop.MetadataEditor.AddPicture(MetadataHandle, path), "Failed to append picture");
404         }
405
406         /// <summary>
407         /// Removes the picture from the media file.
408         /// </summary>
409         /// <since_tizen> 3 </since_tizen>
410         /// <param name="index"> Index of picture to remove </param>
411         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
412         /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
413         public void RemovePicture(int index)
414         {
415             if (index < 0)
416             {
417                 throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
418             }
419
420             MetadataEditorErrorFactory.ThrowIfError(
421                 Interop.MetadataEditor.RemovePicture(MetadataHandle, index), "Failed to remove picture");
422         }
423
424         /// <summary>
425         /// Metadata Editor destructor
426         /// </summary>
427         /// <since_tizen> 3 </since_tizen>
428         ~MetadataEditor()
429         {
430             Dispose(false);
431         }
432
433         protected virtual void Dispose(bool disposing)
434         {
435             if (!_disposed)
436             {
437                 if (disposing)
438                 {
439                     // To be used if there are any other disposable objects
440                 }
441
442                 if (_handle != IntPtr.Zero)
443                 {
444                     Interop.MetadataEditor.Destroy(_handle);
445                     _handle = IntPtr.Zero;
446                 }
447
448                 _disposed = true;
449             }
450         }
451
452         public void Dispose()
453         {
454             Dispose(true);
455             GC.SuppressFinalize(this);
456         }
457     }
458 }