Merge "Added CodecNotSupportedException." 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         /// <param name="path"> The path of the media file to edit metadata </param>
59         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
60         /// <exception cref="NotSupportedException">The file is unsupported format.</exception>
61         /// <exception cref="System.IO.FileNotFoundException">The file does not exist.</exception>
62         public MetadataEditor(string path)
63         {
64             if (path == null)
65             {
66                 throw new ArgumentNullException(nameof(path));
67             }
68
69             MetadataEditorError ret = Interop.MetadataEditor.Create(out _handle);
70             MetadataEditorErrorFactory.ThrowIfError(ret, "Failed to create metadata");
71
72             try
73             {
74                 MetadataEditorErrorFactory.ThrowIfError(
75                     Interop.MetadataEditor.SetPath(MetadataHandle, path), "Failed to set path");
76             }
77             catch (Exception)
78             {
79                 Interop.MetadataEditor.Destroy(_handle);
80                 _handle = IntPtr.Zero;
81                 throw;
82             }
83         }
84
85         private string GetParam(MetadataEditorAttr attr)
86         {
87             IntPtr val = IntPtr.Zero;
88
89             try
90             {
91                 MetadataEditorError e = Interop.MetadataEditor.GetMetadata(MetadataHandle, attr, out val);
92                 MetadataEditorErrorFactory.ThrowIfError(e, "Failed to get metadata");
93
94                 return Marshal.PtrToStringAnsi(val);
95             }
96             finally
97             {
98                 Interop.Libc.Free(val);
99             }
100         }
101
102         private void SetParam(MetadataEditorAttr attr, string value)
103         {
104             MetadataEditorErrorFactory.ThrowIfError(
105                     Interop.MetadataEditor.SetMetadata(MetadataHandle, attr, value), "Fail to set value");
106         }
107
108         /// <summary>
109         /// Artist of media
110         /// </summary>
111         public string Artist
112         {
113             get
114             {
115                 return GetParam(MetadataEditorAttr.Artist);
116             }
117
118             set
119             {
120                 SetParam(MetadataEditorAttr.Artist, value);
121             }
122         }
123
124         /// <summary>
125         /// Title of media
126         /// </summary>
127         public string Title
128         {
129             get
130             {
131                 return GetParam(MetadataEditorAttr.Title);
132             }
133
134             set
135             {
136                 SetParam(MetadataEditorAttr.Title, value);
137             }
138         }
139
140         /// <summary>
141         /// Album name of media
142         /// </summary>
143         public string Album
144         {
145             get
146             {
147                 return GetParam(MetadataEditorAttr.Album);
148             }
149
150             set
151             {
152                 SetParam(MetadataEditorAttr.Album, value);
153             }
154         }
155
156         /// <summary>
157         /// Genre of media
158         /// </summary>
159         public string Genre
160         {
161             get
162             {
163                 return GetParam(MetadataEditorAttr.Genre);
164             }
165
166             set
167             {
168                 SetParam(MetadataEditorAttr.Genre, value);
169             }
170         }
171
172         /// <summary>
173         /// Author of media
174         /// </summary>
175         public string Author
176         {
177             get
178             {
179                 return GetParam(MetadataEditorAttr.Author);
180             }
181
182             set
183             {
184                 SetParam(MetadataEditorAttr.Author, value);
185             }
186         }
187
188         /// <summary>
189         /// Copyright of media
190         /// </summary>
191         public string Copyright
192         {
193             get
194             {
195                 return GetParam(MetadataEditorAttr.Copyright);
196             }
197
198             set
199             {
200                 SetParam(MetadataEditorAttr.Copyright, value);
201             }
202         }
203
204         /// <summary>
205         /// Date of media
206         /// </summary>
207         /// <remarks>
208         /// If the added media contains ID3 tag, This parameter refers to the recording time.
209         /// If the added media is a mp4 format, This parameter refers to the year.
210         /// </remarks>
211         public string Date
212         {
213             get
214             {
215                 return GetParam(MetadataEditorAttr.Date);
216             }
217
218             set
219             {
220                 SetParam(MetadataEditorAttr.Date, value);
221             }
222         }
223
224         /// <summary>
225         /// Description of media
226         /// </summary>
227         public string Description
228         {
229             get
230             {
231                 return GetParam(MetadataEditorAttr.Description);
232             }
233
234             set
235             {
236                 SetParam(MetadataEditorAttr.Description, value);
237             }
238         }
239
240         /// <summary>
241         /// Comment of media
242         /// </summary>
243         public string Comment
244         {
245             get
246             {
247                 return GetParam(MetadataEditorAttr.Comment);
248             }
249
250             set
251             {
252                 SetParam(MetadataEditorAttr.Comment, value);
253             }
254         }
255
256         /// <summary>
257         /// Track number of media
258         /// </summary>
259         public string TrackNumber
260         {
261             get
262             {
263                 return GetParam(MetadataEditorAttr.TrackNumber);
264             }
265
266             set
267             {
268                 SetParam(MetadataEditorAttr.TrackNumber, value);
269             }
270         }
271
272         /// <summary>
273         /// Album art count of media
274         /// </summary>
275         public string PictureCount
276         {
277             get
278             {
279                 return GetParam(MetadataEditorAttr.PictureCount);
280             }
281         }
282
283         /// <summary>
284         /// Conductor of media
285         /// </summary>
286         public string Conductor
287         {
288             get
289             {
290                 return GetParam(MetadataEditorAttr.Conductor);
291             }
292
293             set
294             {
295                 SetParam(MetadataEditorAttr.Conductor, value);
296             }
297         }
298
299         /// <summary>
300         /// Unsynchronized lyric of media
301         /// </summary>
302         public string UnsyncLyrics
303         {
304             get
305             {
306                 return GetParam(MetadataEditorAttr.UnsyncLyrics);
307             }
308
309             set
310             {
311                 SetParam(MetadataEditorAttr.UnsyncLyrics, value);
312             }
313         }
314
315         /// <summary>
316         /// Writes the modified metadata to a media file
317         /// </summary>
318         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
319         public void Commit()
320         {
321             MetadataEditorErrorFactory.ThrowIfError(
322                 Interop.MetadataEditor.UpdateMetadata(MetadataHandle), "Failed to update file");
323         }
324
325         /// <summary>
326         /// Gets the artwork image in a media file
327         /// </summary>
328         /// <param name="index"> Index of picture to import </param>
329         /// <returns> Artwork included in the media file</returns>
330         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
331         /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
332         public Artwork GetPicture(int index)
333         {
334             if (index < 0)
335             {
336                 throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
337             }
338
339             IntPtr data = IntPtr.Zero;
340             int size;
341             IntPtr mimeType = IntPtr.Zero;
342
343             try
344             {
345                 MetadataEditorErrorFactory.ThrowIfError(
346                     Interop.MetadataEditor.GetPicture(MetadataHandle, index, out data, out size, out mimeType), "Failed to get the value");
347
348                 if (size > 0)
349                 {
350                     byte[] tmpBuf = new byte[size];
351                     Marshal.Copy(data, tmpBuf, 0, size);
352
353                     return new Artwork(tmpBuf, Marshal.PtrToStringAnsi(mimeType));
354                 }
355
356                 return null;
357             }
358             finally
359             {
360                 if (data != IntPtr.Zero)
361                 {
362                     Interop.Libc.Free(data);
363                 }
364
365                 if (mimeType != IntPtr.Zero)
366                 {
367                     Interop.Libc.Free(mimeType);
368                 }
369             }
370         }
371
372         /// <summary>
373         /// Appends the picture to the media file.
374         /// </summary>
375         /// <param name="path">The path of picture for adding to the metadata.</param>
376         /// <exception cref="InvalidOperationException">Internal error occurs.</exception>
377         /// <exception cref="ArgumentNullException"><paramref name="path"/> is null.</exception>
378         public void AddPicture(string path)
379         {
380             if (path == null)
381             {
382                 throw new ArgumentNullException(nameof(path));
383             }
384
385             MetadataEditorErrorFactory.ThrowIfError(
386                 Interop.MetadataEditor.AddPicture(MetadataHandle, path), "Failed to append picture");
387         }
388
389         /// <summary>
390         /// Removes the picture from the media file.
391         /// </summary>
392         /// <param name="index"> Index of picture to remove </param>
393         /// <exception cref="InvalidOperationException"> When internal process error is occured</exception>
394         /// <exception cref="ArgumentOutOfRangeException"> Wrong index number </exception>
395         public void RemovePicture(int index)
396         {
397             if (index < 0)
398             {
399                 throw new ArgumentOutOfRangeException("Index should be larger than 0 [" + index + "]");
400             }
401
402             MetadataEditorErrorFactory.ThrowIfError(
403                 Interop.MetadataEditor.RemovePicture(MetadataHandle, index), "Failed to remove picture");
404         }
405
406         /// <summary>
407         /// Metadata Editor destructor
408         /// </summary>
409         ~MetadataEditor()
410         {
411             Dispose(false);
412         }
413
414         protected virtual void Dispose(bool disposing)
415         {
416             if (!_disposed)
417             {
418                 if (disposing)
419                 {
420                     // To be used if there are any other disposable objects
421                 }
422
423                 if (_handle != IntPtr.Zero)
424                 {
425                     Interop.MetadataEditor.Destroy(_handle);
426                     _handle = IntPtr.Zero;
427                 }
428
429                 _disposed = true;
430             }
431         }
432
433         public void Dispose()
434         {
435             Dispose(true);
436             GC.SuppressFinalize(this);
437         }
438     }
439 }