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;
24 namespace Tizen.Multimedia
26 public partial class Player
28 private void RetrieveProperties()
30 NativePlayer.GetAudioLatencyMode(Handle, out _audioLatencyMode).
31 ThrowIfFailed("Failed to initialize the player");
33 NativePlayer.IsLooping(Handle, out _isLooping).ThrowIfFailed("Failed to initialize the player");
37 /// Gets the native handle of the player.
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>
45 ValidateNotDisposed();
46 return _handle.DangerousGetHandle();
50 #region Network configuration
51 private string _cookie = "";
52 private string _userAgent = "";
55 /// Gets or Sets the cookie for streaming playback.
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>
65 Log.Info(PlayerLog.Tag, "get cookie : " + _cookie);
70 ValidatePlayerState(PlayerState.Idle);
74 throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
77 NativePlayer.SetStreamingCookie(Handle, value, value.Length).
78 ThrowIfFailed("Failed to set the cookie to the player");
85 /// Gets or Sets the user agent for streaming playback.
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
95 Log.Info(PlayerLog.Tag, "get useragent : " + _userAgent);
100 ValidatePlayerState(PlayerState.Idle);
104 throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
107 NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
108 ThrowIfFailed("Failed to set the user agent to the player");
116 /// Gets the state of the player.
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
124 ValidateNotDisposed();
128 return PlayerState.Preparing;
131 NativePlayer.GetState(Handle, out var state).ThrowIfFailed("Failed to retrieve the state of the player");
133 Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
135 return (PlayerState)state;
139 private AudioLatencyMode _audioLatencyMode;
142 /// Gets or sets the audio latency mode.
144 /// <value>A <see cref="AudioLatencyMode"/> that specifies the mode. The default is <see cref="AudioLatencyMode.Mid"/>.</value>
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"/>).
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
156 Log.Info(PlayerLog.Tag, "get audio latency mode : " + _audioLatencyMode);
157 return _audioLatencyMode;
161 ValidateNotDisposed();
163 if (_audioLatencyMode == value)
167 ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
169 NativePlayer.SetAudioLatencyMode(Handle, value).
170 ThrowIfFailed("Failed to set the audio latency mode of the player");
172 _audioLatencyMode = value;
176 private bool _isLooping;
179 /// Gets or sets the looping state.
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
187 Log.Info(PlayerLog.Tag, "get looping : " + _isLooping);
192 ValidateNotDisposed();
194 if (_isLooping == value)
199 NativePlayer.SetLooping(Handle, value).ThrowIfFailed("Failed to set the looping state of the player");
205 #region Display methods
207 /// Gets the display settings.
209 /// <value>A <see cref="PlayerDisplaySettings"/> that specifies the display settings.</value>
210 public PlayerDisplaySettings DisplaySettings { get; }
212 private Display _display;
214 private PlayerErrorCode SetDisplay(Display display)
218 Log.Info(PlayerLog.Tag, "set display to none");
219 return NativePlayer.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 NativePlayer.SetDisplay(Handle,
273 type == DisplayType.Overlay ? PlayerDisplayType.Overlay : PlayerDisplayType.Evas, evasObject);
277 private PlayerTrackInfo _audioTrack;
280 /// Gets the track info for audio.
282 /// <value>A <see cref="PlayerTrackInfo"/> for audio.</value>
283 public PlayerTrackInfo AudioTrackInfo
287 if (_audioTrack == null)
289 _audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
295 private PlayerTrackInfo _subtitleTrackInfo;
298 /// Gets the track info for subtitle.
300 /// <value>A <see cref="PlayerTrackInfo"/> for subtitle.</value>
301 public PlayerTrackInfo SubtitleTrackInfo
305 if (_subtitleTrackInfo == null)
307 _subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
309 return _subtitleTrackInfo;
313 private StreamInfo _streamInfo;
316 /// Gets the stream information.
318 /// <value>A <see cref="StreamInfo"/> for this player.</value>
319 public StreamInfo StreamInfo
323 if (_streamInfo == null)
325 _streamInfo = new StreamInfo(this);
331 private readonly AudioEffect _audioEffect;
334 /// Gets the audio effect.
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
342 if (_audioEffect == null)
344 throw new NotSupportedException($"The feature({Features.AudioEffect}) is not supported.");
352 /// Gets or sets the mute state.
354 /// <value>true if the player is muted; otherwise, false.</value>
355 /// <exception cref="ObjectDisposedException">The player has already been disposed of.</exception>
361 NativePlayer.IsMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state of the player");
363 Log.Info(PlayerLog.Tag, "get mute : " + value);
369 NativePlayer.SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state of the player");
374 /// Gets or sets the current volume.
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
381 /// <paramref name="value"/> is greater than 1.0.
388 NativePlayer.GetVolume(Handle, out value, out value).
389 ThrowIfFailed("Failed to get the volume of the player");
394 if (value < 0F || 1.0F < value)
396 throw new ArgumentOutOfRangeException(nameof(value), value,
397 $"Valid volume range is 0 <= value <= 1.0, but got { value }.");
400 NativePlayer.SetVolume(Handle, value, value).
401 ThrowIfFailed("Failed to set the volume of the player");