2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 using System.Threading.Tasks;
18 using System.Runtime.InteropServices;
19 using System.Diagnostics;
21 using System.Threading;
22 using NativeDisplay = Interop.Display;
25 namespace Tizen.Multimedia
27 /// <since_tizen> 3 </since_tizen>
28 public partial class Player
30 private void RetrieveProperties()
32 NativePlayer.GetAudioLatencyMode(Handle, out _audioLatencyMode).
33 ThrowIfFailed("Failed to initialize the player");
35 NativePlayer.IsLooping(Handle, out _isLooping).ThrowIfFailed("Failed to initialize the player");
39 /// Gets the native handle of the player.
41 /// <value>An IntPtr that contains the native handle of the player.</value>
42 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
43 /// <since_tizen> 3 </since_tizen>
48 ValidateNotDisposed();
49 return _handle.DangerousGetHandle();
53 #region Network configuration
54 private string _cookie = "";
55 private string _userAgent = "";
58 /// Gets or sets the cookie for streaming playback.
60 /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
61 /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
62 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
63 /// <exception cref="ArgumentNullException">The value to set is null.</exception>
64 /// <since_tizen> 3 </since_tizen>
69 Log.Info(PlayerLog.Tag, "get cookie : " + _cookie);
74 ValidatePlayerState(PlayerState.Idle);
78 throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
81 NativePlayer.SetStreamingCookie(Handle, value, value.Length).
82 ThrowIfFailed("Failed to set the cookie to the player");
89 /// Gets or sets the user agent for streaming playback.
91 /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
92 /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
93 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
94 /// <exception cref="ArgumentNullException">The value to set is null.</exception>
95 /// <since_tizen> 3 </since_tizen>
96 public string UserAgent
100 Log.Info(PlayerLog.Tag, "get useragent : " + _userAgent);
105 ValidatePlayerState(PlayerState.Idle);
109 throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
112 NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
113 ThrowIfFailed("Failed to set the user agent to the player");
121 /// Gets the state of the player.
123 /// <value>The current state of the player.</value>
124 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
125 /// <since_tizen> 3 </since_tizen>
126 public PlayerState State
130 ValidateNotDisposed();
134 return PlayerState.Preparing;
137 NativePlayer.GetState(Handle, out var state).ThrowIfFailed("Failed to retrieve the state of the player");
139 Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
141 return (PlayerState)state;
145 private AudioLatencyMode _audioLatencyMode;
148 /// Gets or sets the audio latency mode.
150 /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
152 /// If the mode is <see cref="AudioLatencyMode.High"/>,
153 /// audio output interval can be increased, so it can keep more audio data to play.
154 /// But, state transition like pause or resume can be more slower than default(<see cref="AudioLatencyMode.Mid"/>).
156 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
157 /// <exception cref="ArgumentException">The value is not valid.</exception>
158 /// <since_tizen> 3 </since_tizen>
159 public AudioLatencyMode AudioLatencyMode
163 Log.Info(PlayerLog.Tag, "get audio latency mode : " + _audioLatencyMode);
164 return _audioLatencyMode;
168 ValidateNotDisposed();
170 if (_audioLatencyMode == value)
174 ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
176 NativePlayer.SetAudioLatencyMode(Handle, value).
177 ThrowIfFailed("Failed to set the audio latency mode of the player");
179 _audioLatencyMode = value;
183 private bool _isLooping;
186 /// Gets or sets the looping state.
188 /// <value>true if the playback is looping; otherwise, false. The default value is false.</value>
189 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
190 /// <since_tizen> 3 </since_tizen>
191 public bool IsLooping
195 Log.Info(PlayerLog.Tag, "get looping : " + _isLooping);
200 ValidateNotDisposed();
202 if (_isLooping == value)
207 NativePlayer.SetLooping(Handle, value).ThrowIfFailed("Failed to set the looping state of the player");
213 #region Display methods
215 /// Gets the display settings.
217 /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
218 /// <since_tizen> 3 </since_tizen>
219 public PlayerDisplaySettings DisplaySettings { get; }
221 private Display _display;
223 private PlayerErrorCode SetDisplay(Display display)
227 return NativeDisplay.SetDisplay(Handle, PlayerDisplayType.None, IntPtr.Zero);
230 return display.ApplyTo(this);
233 private void ReplaceDisplay(Display newDisplay)
235 _display?.SetOwner(null);
236 _display = newDisplay;
237 _display?.SetOwner(this);
241 /// Gets or sets the display.
243 /// <value>A <see cref="Multimedia.Display"/> that specifies the display.</value>
245 /// The player must be in the <see cref="PlayerState.Idle"/> state.<br/>
246 /// The raw video feature(http://tizen.org/feature/multimedia.raw_video) is required if
247 /// the display is created with <see cref="MediaView"/>.
249 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
250 /// <exception cref="ArgumentException">The value has already been assigned to another player.</exception>
251 /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
252 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
253 /// <since_tizen> 3 </since_tizen>
254 public Display Display
262 ValidatePlayerState(PlayerState.Idle);
264 if (value != null && value.HasMediaView)
266 ValidationUtil.ValidateFeatureSupported(PlayerFeatures.RawVideo);
269 if (value?.Owner != null)
271 if (ReferenceEquals(this, value.Owner))
276 throw new ArgumentException("The display has already been assigned to another.");
279 ReplaceDisplay(value);
283 PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
285 Debug.Assert(IsDisposed == false);
287 Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
288 Debug.Assert(type != DisplayType.None);
290 return NativeDisplay.SetDisplay(Handle,
291 type == DisplayType.Overlay ? PlayerDisplayType.Overlay : PlayerDisplayType.Evas, evasObject);
294 PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEcoreWindow(IntPtr windowHandle)
296 Debug.Assert(IsDisposed == false);
298 return NativeDisplay.SetEcoreDisplay(Handle, PlayerDisplayType.Overlay, windowHandle);
302 private PlayerTrackInfo _audioTrack;
305 /// Gets the track info for the audio.
307 /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
308 /// <since_tizen> 3 </since_tizen>
309 public PlayerTrackInfo AudioTrackInfo
313 if (_audioTrack == null)
315 _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
321 private PlayerTrackInfo _subtitleTrackInfo;
324 /// Gets the track info for the subtitle.
326 /// <value>A <see cref="PlayerTrackInfo"/> for the subtitle.</value>
327 /// <since_tizen> 3 </since_tizen>
328 public PlayerTrackInfo SubtitleTrackInfo
332 if (_subtitleTrackInfo == null)
334 _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
336 return _subtitleTrackInfo;
340 private StreamInfo _streamInfo;
343 /// Gets the stream information.
345 /// <value>A <see cref="StreamInfo"/> for this player.</value>
346 /// <since_tizen> 3 </since_tizen>
347 public StreamInfo StreamInfo
351 if (_streamInfo == null)
353 _streamInfo = new StreamInfo(this);
359 private readonly AudioEffect _audioEffect;
362 /// Gets the audio effect.
364 /// <feature>http://tizen.org/feature/multimedia.custom_audio_effect</feature>
365 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
366 /// <since_tizen> 3 </since_tizen>
367 public AudioEffect AudioEffect
371 if (_audioEffect == null)
373 throw new NotSupportedException($"The feature({PlayerFeatures.AudioEffect}) is not supported.");
381 /// Gets or sets the mute state.
383 /// <value>true if the player is muted; otherwise, false.</value>
384 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
385 /// <since_tizen> 3 </since_tizen>
391 NativePlayer.IsMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state of the player");
393 Log.Info(PlayerLog.Tag, "get mute : " + value);
399 NativePlayer.SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state of the player");
404 /// Gets or sets the current volume.
406 /// <remarks>Valid volume range is from 0 to 1.0, inclusive.</remarks>
407 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
408 /// <exception cref="ArgumentOutOfRangeException">
409 /// <paramref name="value"/> is less than zero.<br/>
411 /// <paramref name="value"/> is greater than 1.0.
413 /// <since_tizen> 3 </since_tizen>
419 NativePlayer.GetVolume(Handle, out value, out value).
420 ThrowIfFailed("Failed to get the volume of the player");
425 if (value < 0F || 1.0F < value)
427 throw new ArgumentOutOfRangeException(nameof(value), value,
428 $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
431 NativePlayer.SetVolume(Handle, value, value).
432 ThrowIfFailed("Failed to set the volume of the player");