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 public partial class Player
29 private void RetrieveProperties()
31 NativePlayer.GetAudioLatencyMode(Handle, out _audioLatencyMode).
32 ThrowIfFailed("Failed to initialize the player");
34 NativePlayer.IsLooping(Handle, out _isLooping).ThrowIfFailed("Failed to initialize the player");
38 /// Gets the native handle of the player.
40 /// <value>An IntPtr that contains the native handle of the player.</value>
41 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
46 ValidateNotDisposed();
47 return _handle.DangerousGetHandle();
51 #region Network configuration
52 private string _cookie = "";
53 private string _userAgent = "";
56 /// Gets or Sets the cookie for streaming playback.
58 /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
59 /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
60 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
61 /// <exception cref="ArgumentNullException">The value to set is null.</exception>
66 Log.Info(PlayerLog.Tag, "get cookie : " + _cookie);
71 ValidatePlayerState(PlayerState.Idle);
75 throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
78 NativePlayer.SetStreamingCookie(Handle, value, value.Length).
79 ThrowIfFailed("Failed to set the cookie to the player");
86 /// Gets or Sets the user agent for streaming playback.
88 /// <remarks>To set, the player must be in the <see cref="PlayerState.Idle"/> state.</remarks>
89 /// <exception cref="InvalidOperationException">The player is not in the valid state.</exception>
90 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
91 /// <exception cref="ArgumentNullException">The value to set is null.</exception>
92 public string UserAgent
96 Log.Info(PlayerLog.Tag, "get useragent : " + _userAgent);
101 ValidatePlayerState(PlayerState.Idle);
105 throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
108 NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
109 ThrowIfFailed("Failed to set the user agent to the player");
117 /// Gets the state of the player.
119 /// <value>The current state of the player.</value>
120 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
121 public PlayerState State
125 ValidateNotDisposed();
129 return PlayerState.Preparing;
132 NativePlayer.GetState(Handle, out var state).ThrowIfFailed("Failed to retrieve the state of the player");
134 Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
136 return (PlayerState)state;
140 private AudioLatencyMode _audioLatencyMode;
143 /// Gets or sets the audio latency mode.
145 /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
147 /// If the mode is <see cref="AudioLatencyMode.High"/>,
148 /// audio output interval can be increased so, it can keep more audio data to play.
149 /// But, state transition like pause or resume can be more slower than default(<see cref="AudioLatencyMode.Mid"/>).
151 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
152 /// <exception cref="ArgumentException">The value is not valid.</exception>
153 public AudioLatencyMode AudioLatencyMode
157 Log.Info(PlayerLog.Tag, "get audio latency mode : " + _audioLatencyMode);
158 return _audioLatencyMode;
162 ValidateNotDisposed();
164 if (_audioLatencyMode == value)
168 ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
170 NativePlayer.SetAudioLatencyMode(Handle, value).
171 ThrowIfFailed("Failed to set the audio latency mode of the player");
173 _audioLatencyMode = value;
177 private bool _isLooping;
180 /// Gets or sets the looping state.
182 /// <value>true if the playback is looping; otherwise, false. The default value is false.</value>
183 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
184 public bool IsLooping
188 Log.Info(PlayerLog.Tag, "get looping : " + _isLooping);
193 ValidateNotDisposed();
195 if (_isLooping == value)
200 NativePlayer.SetLooping(Handle, value).ThrowIfFailed("Failed to set the looping state of the player");
206 #region Display methods
208 /// Gets the display settings.
210 /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
211 public PlayerDisplaySettings DisplaySettings { get; }
213 private Display _display;
215 private PlayerErrorCode SetDisplay(Display display)
219 return NativeDisplay.SetDisplay(Handle, PlayerDisplayType.None, IntPtr.Zero);
222 return display.ApplyTo(this);
225 private void ReplaceDisplay(Display newDisplay)
227 _display?.SetOwner(null);
228 _display = newDisplay;
229 _display?.SetOwner(this);
233 /// Gets or sets the display.
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
248 ValidatePlayerState(PlayerState.Idle);
250 if (value?.Owner != null)
252 if (ReferenceEquals(this, value.Owner))
257 throw new ArgumentException("The display has already been assigned to another.");
259 SetDisplay(value).ThrowIfFailed("Failed to set the display to the player");
261 ReplaceDisplay(value);
265 PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
267 Debug.Assert(IsDisposed == false);
269 Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
270 Debug.Assert(type != DisplayType.None);
272 return NativeDisplay.SetDisplay(Handle,
273 type == DisplayType.Overlay ? PlayerDisplayType.Overlay : PlayerDisplayType.Evas, evasObject);
276 PlayerErrorCode IDisplayable<PlayerErrorCode>.ApplyEcoreWindow(IntPtr windowHandle)
278 Debug.Assert(IsDisposed == false);
280 return NativeDisplay.SetEcoreDisplay(Handle, PlayerDisplayType.Overlay, windowHandle);
284 private PlayerTrackInfo _audioTrack;
287 /// Gets the track info for audio.
289 /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
290 public PlayerTrackInfo AudioTrackInfo
294 if (_audioTrack == null)
296 _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
302 private PlayerTrackInfo _subtitleTrackInfo;
305 /// Gets the track info for subtitle.
307 /// <value>A <see cref="PlayerTrackInfo"/> for subtitle.</value>
308 public PlayerTrackInfo SubtitleTrackInfo
312 if (_subtitleTrackInfo == null)
314 _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
316 return _subtitleTrackInfo;
320 private StreamInfo _streamInfo;
323 /// Gets the stream information.
325 /// <value>A <see cref="StreamInfo"/> for this player.</value>
326 public StreamInfo StreamInfo
330 if (_streamInfo == null)
332 _streamInfo = new StreamInfo(this);
338 private readonly AudioEffect _audioEffect;
341 /// Gets the audio effect.
343 /// <feature>http://tizen.org/feature/multimedia.custom_audio_effect</feature>
344 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
345 public AudioEffect AudioEffect
349 if (_audioEffect == null)
351 throw new NotSupportedException($"The feature({Features.AudioEffect}) is not supported.");
359 /// Gets or sets the mute state.
361 /// <value>true if the player is muted; otherwise, false.</value>
362 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
368 NativePlayer.IsMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state of the player");
370 Log.Info(PlayerLog.Tag, "get mute : " + value);
376 NativePlayer.SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state of the player");
381 /// Gets or sets the current volume.
383 /// <remarks>Valid volume range is from 0 to 1.0, inclusive.</remarks>
384 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
385 /// <exception cref="ArgumentOutOfRangeException">
386 /// <paramref name="value"/> is less than zero.\n
388 /// <paramref name="value"/> is greater than 1.0.
395 NativePlayer.GetVolume(Handle, out value, out value).
396 ThrowIfFailed("Failed to get the volume of the player");
401 if (value < 0F || 1.0F < value)
403 throw new ArgumentOutOfRangeException(nameof(value), value,
404 $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
407 NativePlayer.SetVolume(Handle, value, value).
408 ThrowIfFailed("Failed to set the volume of the player");