[MediaPlayer] Added ErrorHandler registration methods for internal use. (#33)
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.MediaPlayer / Player / Player.Properties.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 using System;
17 using System.Threading.Tasks;
18 using System.Runtime.InteropServices;
19 using System.Diagnostics;
20 using System.IO;
21 using System.Threading;
22 using NativeDisplay = Interop.Display;
23 using static Interop;
24
25 namespace Tizen.Multimedia
26 {
27     /// <since_tizen> 3 </since_tizen>
28     public partial class Player
29     {
30         /// <summary>
31         /// Gets the native handle of the player.
32         /// </summary>
33         /// <value>An IntPtr that contains the native handle of the player.</value>
34         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
35         /// <since_tizen> 3 </since_tizen>
36         public IntPtr Handle
37         {
38             get
39             {
40                 ValidateNotDisposed();
41                 return _handle.DangerousGetHandle();
42             }
43         }
44
45         #region Network configuration
46         private string _cookie = "";
47         private string _userAgent = "";
48
49         /// <summary>
50         /// Gets or sets the cookie for streaming playback.
51         /// </summary>
52         /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
53         /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
54         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
55         /// <exception cref="ArgumentNullException">The value to set is null.</exception>
56         /// <since_tizen> 3 </since_tizen>
57         public string Cookie
58         {
59             get
60             {
61                 return _cookie;
62             }
63             set
64             {
65                 ValidatePlayerState(PlayerState.Idle);
66
67                 if (value == null)
68                 {
69                     throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
70                 }
71
72                 NativePlayer.SetStreamingCookie(Handle, value, value.Length).
73                     ThrowIfFailed(this, "Failed to set the cookie to the player");
74
75                 _cookie = value;
76             }
77         }
78
79         /// <summary>
80         /// Gets or sets the user agent for streaming playback.
81         /// </summary>
82         /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
83         /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
84         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
85         /// <exception cref="ArgumentNullException">The value to set is null.</exception>
86         /// <since_tizen> 3 </since_tizen>
87         public string UserAgent
88         {
89             get
90             {
91                 return _userAgent;
92             }
93             set
94             {
95                 ValidatePlayerState(PlayerState.Idle);
96
97                 if (value == null)
98                 {
99                     throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
100                 }
101
102                 NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
103                     ThrowIfFailed(this, "Failed to set the user agent to the player");
104
105                 _userAgent = value;
106             }
107         }
108         #endregion
109
110         /// <summary>
111         /// Gets the state of the player.
112         /// </summary>
113         /// <value>The current state of the player.</value>
114         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
115         /// <since_tizen> 3 </since_tizen>
116         public PlayerState State
117         {
118             get
119             {
120                 ValidateNotDisposed();
121
122                 if (IsPreparing())
123                 {
124                     return PlayerState.Preparing;
125                 }
126
127                 NativePlayer.GetState(Handle, out var state).
128                     ThrowIfFailed(this, "Failed to retrieve the state of the player");
129
130                 Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
131
132                 return (PlayerState)state;
133             }
134         }
135
136         /// <summary>
137         /// Gets or sets the audio latency mode.
138         /// </summary>
139         /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
140         /// <remarks>
141         /// If the mode is <see cref="AudioLatencyMode.High"/>,
142         /// audio output interval can be increased, so it can keep more audio data to play.
143         /// But, state transition like pause or resume can be more slower than default(<see cref="AudioLatencyMode.Mid"/>).
144         /// </remarks>
145         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
146         /// <exception cref="ArgumentException">The value is not valid.</exception>
147         /// <since_tizen> 3 </since_tizen>
148         public AudioLatencyMode AudioLatencyMode
149         {
150             get
151             {
152                 NativePlayer.GetAudioLatencyMode(Handle, out var value).
153                     ThrowIfFailed(this, "Failed to get the audio latency mode of the player");
154
155                 return value;
156             }
157             set
158             {
159                 ValidateNotDisposed();
160
161                 ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
162
163                 NativePlayer.SetAudioLatencyMode(Handle, value).
164                     ThrowIfFailed(this, "Failed to set the audio latency mode of the player");
165             }
166         }
167
168         /// <summary>
169         /// Gets or sets the looping state.
170         /// </summary>
171         /// <value>true if the playback is looping; otherwise, false. The default value is false.</value>
172         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
173         /// <since_tizen> 3 </since_tizen>
174         public bool IsLooping
175         {
176             get
177             {
178                 NativePlayer.IsLooping(Handle, out var value).
179                     ThrowIfFailed(this, "Failed to get the looping state of the player");
180
181                 return value;
182             }
183             set
184             {
185                 ValidateNotDisposed();
186
187                 NativePlayer.SetLooping(Handle, value).
188                     ThrowIfFailed(this, "Failed to set the looping state of the player");
189             }
190         }
191
192         #region Display methods
193
194         /// <summary>
195         /// Gets the display settings.
196         /// </summary>
197         /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
198         /// <since_tizen> 3 </since_tizen>
199         public PlayerDisplaySettings DisplaySettings { get; }
200
201         private Display _display;
202
203         private PlayerErrorCode SetDisplay(Display display)
204         {
205             if (display == null)
206             {
207                 return NativeDisplay.SetDisplay(Handle, PlayerDisplayType.None, IntPtr.Zero);
208             }
209
210             return display.ApplyTo(this);
211         }
212
213         private void ReplaceDisplay(Display newDisplay)
214         {
215             _display?.SetOwner(null);
216             _display = newDisplay;
217             _display?.SetOwner(this);
218         }
219
220         /// <summary>
221         /// Gets or sets the display.
222         /// </summary>
223         /// <value>A <see cref="Multimedia.Display"/> that specifies the display.</value>
224         /// <remarks>
225         ///     The player must be in the <see cref="PlayerState.Idle"/> state.<br/>
226         ///     The raw video feature(http://tizen.org/feature/multimedia.raw_video) is required if
227         ///     the display is created with <see cref="MediaView"/>.
228         /// </remarks>
229         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
230         /// <exception cref="ArgumentException">The value has already been assigned to another player.</exception>
231         /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
232         /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
233         /// <since_tizen> 3 </since_tizen>
234         public Display Display
235         {
236             get
237             {
238                 return _display;
239             }
240             set
241             {
242                 ValidatePlayerState(PlayerState.Idle);
243
244                 if (value != null && value.HasMediaView)
245                 {
246                     ValidationUtil.ValidateFeatureSupported(PlayerFeatures.RawVideo);
247                 }
248
249                 if (value?.Owner != null)
250                 {
251                     if (ReferenceEquals(this, value.Owner))
252                     {
253                         return;
254                     }
255
256                     throw new ArgumentException("The display has already been assigned to another.");
257                 }
258
259                 ReplaceDisplay(value);
260             }
261         }
262
263         PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
264         {
265             Debug.Assert(IsDisposed == false);
266
267             Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
268             Debug.Assert(type != DisplayType.None);
269
270             return NativeDisplay.SetDisplay(Handle,
271                 type == DisplayType.Overlay ? PlayerDisplayType.Overlay : PlayerDisplayType.Evas, evasObject);
272         }
273
274         PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEcoreWindow(IntPtr windowHandle)
275         {
276             Debug.Assert(IsDisposed == false);
277
278             return NativeDisplay.SetEcoreDisplay(Handle, PlayerDisplayType.Overlay, windowHandle);
279         }
280         #endregion
281
282         private PlayerTrackInfo _audioTrack;
283
284         /// <summary>
285         /// Gets the track info for the audio.
286         /// </summary>
287         /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
288         /// <since_tizen> 3 </since_tizen>
289         public PlayerTrackInfo AudioTrackInfo
290         {
291             get
292             {
293                 if (_audioTrack == null)
294                 {
295                     _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
296                 }
297                 return _audioTrack;
298             }
299         }
300
301         private PlayerTrackInfo _subtitleTrackInfo;
302
303         /// <summary>
304         /// Gets the track info for the subtitle.
305         /// </summary>
306         /// <value>A <see cref="PlayerTrackInfo"/> for the subtitle.</value>
307         /// <since_tizen> 3 </since_tizen>
308         public PlayerTrackInfo SubtitleTrackInfo
309         {
310             get
311             {
312                 if (_subtitleTrackInfo == null)
313                 {
314                     _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
315                 }
316                 return _subtitleTrackInfo;
317             }
318         }
319
320         private StreamInfo _streamInfo;
321
322         /// <summary>
323         /// Gets the stream information.
324         /// </summary>
325         /// <value>A <see cref="StreamInfo"/> for this player.</value>
326         /// <since_tizen> 3 </since_tizen>
327         public StreamInfo StreamInfo
328         {
329             get
330             {
331                 if (_streamInfo == null)
332                 {
333                     _streamInfo = new StreamInfo(this);
334                 }
335                 return _streamInfo;
336             }
337         }
338
339         private readonly AudioEffect _audioEffect;
340
341         /// <summary>
342         /// Gets the audio effect.
343         /// </summary>
344         /// <feature>http://tizen.org/feature/multimedia.custom_audio_effect</feature>
345         /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
346         /// <since_tizen> 3 </since_tizen>
347         public AudioEffect AudioEffect
348         {
349             get
350             {
351                 if (_audioEffect == null)
352                 {
353                     throw new NotSupportedException($"The feature({PlayerFeatures.AudioEffect}) is not supported.");
354                 }
355
356                 return _audioEffect;
357             }
358         }
359
360         /// <summary>
361         /// Gets or sets the mute state.
362         /// </summary>
363         /// <value>true if the player is muted; otherwise, false.</value>
364         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
365         /// <since_tizen> 3 </since_tizen>
366         public bool Muted
367         {
368             get
369             {
370                 NativePlayer.IsMuted(Handle, out var value).
371                     ThrowIfFailed(this, "Failed to get the mute state of the player");
372
373                 Log.Info(PlayerLog.Tag, "get mute : " + value);
374
375                 return value;
376             }
377             set
378             {
379                 NativePlayer.SetMute(Handle, value).ThrowIfFailed(this, "Failed to set the mute state of the player");
380             }
381         }
382
383         /// <summary>
384         /// Gets or sets the current volume.
385         /// </summary>
386         /// <remarks>Valid volume range is from 0 to 1.0, inclusive.</remarks>
387         /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
388         /// <exception cref="ArgumentOutOfRangeException">
389         ///     <paramref name="value"/> is less than zero.<br/>
390         ///     -or-<br/>
391         ///     <paramref name="value"/> is greater than 1.0.
392         /// </exception>
393         /// <since_tizen> 3 </since_tizen>
394         public float Volume
395         {
396             get
397             {
398                 float value = 0.0F;
399                 NativePlayer.GetVolume(Handle, out value, out value).
400                     ThrowIfFailed(this, "Failed to get the volume of the player");
401
402                 return value;
403             }
404             set
405             {
406                 if (value < 0F || 1.0F < value)
407                 {
408                     throw new ArgumentOutOfRangeException(nameof(value), value,
409                         $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
410                 }
411
412                 NativePlayer.SetVolume(Handle, value, value).
413                     ThrowIfFailed(this, "Failed to set the volume of the player");
414             }
415         }
416     }
417 }