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