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
31 /// Gets the native handle of the player.
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>
40 ValidateNotDisposed();
41 return _handle.DangerousGetHandle();
45 #region Network configuration
46 private string _cookie = "";
47 private string _userAgent = "";
50 /// Gets or sets the cookie for streaming playback.
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>
65 ValidatePlayerState(PlayerState.Idle);
69 throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
72 NativePlayer.SetStreamingCookie(Handle, value, value.Length).
73 ThrowIfFailed(this, "Failed to set the cookie to the player");
80 /// Gets or sets the user agent for streaming playback.
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
95 ValidatePlayerState(PlayerState.Idle);
99 throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
102 NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
103 ThrowIfFailed(this, "Failed to set the user agent to the player");
111 /// Gets the state of the player.
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
120 ValidateNotDisposed();
124 return PlayerState.Preparing;
127 NativePlayer.GetState(Handle, out var state).
128 ThrowIfFailed(this, "Failed to retrieve the state of the player");
130 Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
132 return (PlayerState)state;
137 /// Gets or sets the audio latency mode.
139 /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
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"/>).
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
152 NativePlayer.GetAudioLatencyMode(Handle, out var value).
153 ThrowIfFailed(this, "Failed to get the audio latency mode of the player");
159 ValidateNotDisposed();
161 ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value, nameof(value));
163 NativePlayer.SetAudioLatencyMode(Handle, value).
164 ThrowIfFailed(this, "Failed to set the audio latency mode of the player");
169 /// Gets or sets the looping state.
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
178 NativePlayer.IsLooping(Handle, out var value).
179 ThrowIfFailed(this, "Failed to get the looping state of the player");
185 ValidateNotDisposed();
187 NativePlayer.SetLooping(Handle, value).
188 ThrowIfFailed(this, "Failed to set the looping state of the player");
192 #region Display methods
194 private PlayerDisplaySettings _displaySettings;
197 /// Gets the display settings.
199 /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
200 /// <since_tizen> 3 </since_tizen>
201 public PlayerDisplaySettings DisplaySettings => _displaySettings;
203 private Display _display;
205 private PlayerErrorCode SetDisplay(Display display)
209 return NativeDisplay.SetDisplay(Handle, PlayerDisplayType.None, IntPtr.Zero);
212 return display.ApplyTo(this);
215 private void ReplaceDisplay(Display newDisplay)
217 _display?.SetOwner(null);
218 _display = newDisplay;
219 _display?.SetOwner(this);
223 /// Gets or sets the display.
225 /// <value>A <see cref="Multimedia.Display"/> that specifies the display.</value>
227 /// The player must be in the <see cref="PlayerState.Idle"/> state.<br/>
228 /// The raw video feature(http://tizen.org/feature/multimedia.raw_video) is required if
229 /// the display is created with <see cref="MediaView"/>.
231 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
232 /// <exception cref="ArgumentException">The value has already been assigned to another player.</exception>
233 /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
234 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
235 /// <since_tizen> 3 </since_tizen>
236 public Display Display
244 ValidatePlayerState(PlayerState.Idle);
246 if (value != null && value.HasMediaView)
248 ValidationUtil.ValidateFeatureSupported(PlayerFeatures.RawVideo);
251 if (value?.Owner != null)
253 if (ReferenceEquals(this, value.Owner))
258 throw new ArgumentException("The display has already been assigned to another.");
261 SetDisplay(value).ThrowIfFailed(this, "Failed to configure display of the player");
263 ReplaceDisplay(value);
267 PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
269 Debug.Assert(IsDisposed == false);
271 Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
272 Debug.Assert(type != DisplayType.None);
274 return NativeDisplay.SetDisplay(Handle,
275 type == DisplayType.Overlay ? PlayerDisplayType.Overlay : PlayerDisplayType.Evas, evasObject);
278 PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEcoreWindow(IntPtr windowHandle)
280 Debug.Assert(IsDisposed == false);
282 return NativeDisplay.SetEcoreDisplay(Handle, PlayerDisplayType.Overlay, windowHandle);
286 private PlayerTrackInfo _audioTrack;
289 /// Gets the track info for the audio.
291 /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
292 /// <since_tizen> 3 </since_tizen>
293 public PlayerTrackInfo AudioTrackInfo
297 if (_audioTrack == null)
299 _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
305 private PlayerTrackInfo _subtitleTrackInfo;
308 /// Gets the track info for the subtitle.
310 /// <value>A <see cref="PlayerTrackInfo"/> for the subtitle.</value>
311 /// <since_tizen> 3 </since_tizen>
312 public PlayerTrackInfo SubtitleTrackInfo
316 if (_subtitleTrackInfo == null)
318 _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
320 return _subtitleTrackInfo;
324 private StreamInfo _streamInfo;
327 /// Gets the stream information.
329 /// <value>A <see cref="StreamInfo"/> for this player.</value>
330 /// <since_tizen> 3 </since_tizen>
331 public StreamInfo StreamInfo
335 if (_streamInfo == null)
337 _streamInfo = new StreamInfo(this);
343 private AudioEffect _audioEffect;
346 /// Gets the audio effect.
348 /// <feature>http://tizen.org/feature/multimedia.custom_audio_effect</feature>
349 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
350 /// <since_tizen> 3 </since_tizen>
351 public AudioEffect AudioEffect
355 if (_audioEffect == null)
357 throw new NotSupportedException($"The feature({PlayerFeatures.AudioEffect}) is not supported.");
365 /// Gets or sets the mute state.
367 /// <value>true if the player is muted; otherwise, false.</value>
368 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
369 /// <since_tizen> 3 </since_tizen>
374 NativePlayer.IsMuted(Handle, out var value).
375 ThrowIfFailed(this, "Failed to get the mute state of the player");
377 Log.Info(PlayerLog.Tag, "get mute : " + value);
383 NativePlayer.SetMute(Handle, value).ThrowIfFailed(this, "Failed to set the mute state of the player");
388 /// Gets or sets the current volume.
390 /// <remarks>Valid volume range is from 0 to 1.0, inclusive.</remarks>
391 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
392 /// <exception cref="ArgumentOutOfRangeException">
393 /// <paramref name="value"/> is less than zero.<br/>
395 /// <paramref name="value"/> is greater than 1.0.
397 /// <since_tizen> 3 </since_tizen>
403 NativePlayer.GetVolume(Handle, out value, out value).
404 ThrowIfFailed(this, "Failed to get the volume of the player");
410 if (value < 0F || 1.0F < value)
412 throw new ArgumentOutOfRangeException(nameof(value), value,
413 $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
416 NativePlayer.SetVolume(Handle, value, value).
417 ThrowIfFailed(this, "Failed to set the volume of the player");