/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Threading;
using NativeDisplay = Interop.Display;
using static Interop;
namespace Tizen.Multimedia
{
public partial class Player
{
private void RetrieveProperties()
{
NativePlayer.GetAudioLatencyMode(Handle, out _audioLatencyMode).
ThrowIfFailed("Failed to initialize the player");
NativePlayer.IsLooping(Handle, out _isLooping).ThrowIfFailed("Failed to initialize the player");
}
///
/// Gets the native handle of the player.
///
/// An IntPtr that contains the native handle of the player.
/// The player has already been disposed of.
public IntPtr Handle
{
get
{
ValidateNotDisposed();
return _handle.DangerousGetHandle();
}
}
#region Network configuration
private string _cookie = "";
private string _userAgent = "";
///
/// Gets or sets the cookie for streaming playback.
///
/// To set, the player must be in the state.
/// The player is not in the valid state.
/// The player has already been disposed of.
/// The value to set is null.
public string Cookie
{
get
{
Log.Info(PlayerLog.Tag, "get cookie : " + _cookie);
return _cookie;
}
set
{
ValidatePlayerState(PlayerState.Idle);
if (value == null)
{
throw new ArgumentNullException(nameof(value), "Cookie can't be null.");
}
NativePlayer.SetStreamingCookie(Handle, value, value.Length).
ThrowIfFailed("Failed to set the cookie to the player");
_cookie = value;
}
}
///
/// Gets or sets the user agent for streaming playback.
///
/// To set, the player must be in the state.
/// The player is not in the valid state.
/// The player has already been disposed of.
/// The value to set is null.
public string UserAgent
{
get
{
Log.Info(PlayerLog.Tag, "get useragent : " + _userAgent);
return _userAgent;
}
set
{
ValidatePlayerState(PlayerState.Idle);
if (value == null)
{
throw new ArgumentNullException(nameof(value), "UserAgent can't be null.");
}
NativePlayer.SetStreamingUserAgent(Handle, value, value.Length).
ThrowIfFailed("Failed to set the user agent to the player");
_userAgent = value;
}
}
#endregion
///
/// Gets the state of the player.
///
/// The current state of the player.
/// The player has already been disposed of.
public PlayerState State
{
get
{
ValidateNotDisposed();
if (IsPreparing())
{
return PlayerState.Preparing;
}
NativePlayer.GetState(Handle, out var state).ThrowIfFailed("Failed to retrieve the state of the player");
Debug.Assert(Enum.IsDefined(typeof(PlayerState), state));
return (PlayerState)state;
}
}
private AudioLatencyMode _audioLatencyMode;
///
/// Gets or sets the audio latency mode.
///
/// A that specifies the mode. The default is .
///
/// If the mode is ,
/// audio output interval can be increased, so it can keep more audio data to play.
/// But, state transition like pause or resume can be more slower than default().
///
/// The player has already been disposed of.
/// The value is not valid.
public AudioLatencyMode AudioLatencyMode
{
get
{
Log.Info(PlayerLog.Tag, "get audio latency mode : " + _audioLatencyMode);
return _audioLatencyMode;
}
set
{
ValidateNotDisposed();
if (_audioLatencyMode == value)
{
return;
}
ValidationUtil.ValidateEnum(typeof(AudioLatencyMode), value);
NativePlayer.SetAudioLatencyMode(Handle, value).
ThrowIfFailed("Failed to set the audio latency mode of the player");
_audioLatencyMode = value;
}
}
private bool _isLooping;
///
/// Gets or sets the looping state.
///
/// true if the playback is looping; otherwise, false. The default value is false.
/// The player has already been disposed of.
public bool IsLooping
{
get
{
Log.Info(PlayerLog.Tag, "get looping : " + _isLooping);
return _isLooping;
}
set
{
ValidateNotDisposed();
if (_isLooping == value)
{
return;
}
NativePlayer.SetLooping(Handle, value).ThrowIfFailed("Failed to set the looping state of the player");
_isLooping = value;
}
}
#region Display methods
///
/// Gets the display settings.
///
/// A that specifies the display settings.
public PlayerDisplaySettings DisplaySettings { get; }
private Display _display;
private PlayerErrorCode SetDisplay(Display display)
{
if (display == null)
{
return NativeDisplay.SetDisplay(Handle, PlayerDisplayType.None, IntPtr.Zero);
}
return display.ApplyTo(this);
}
private void ReplaceDisplay(Display newDisplay)
{
_display?.SetOwner(null);
_display = newDisplay;
_display?.SetOwner(this);
}
///
/// Gets or sets the display.
///
/// A that specifies the display.
/// The player must be in the state.
/// The player has already been disposed of.
/// The value has already been assigned to another player.
/// The player is not in the valid state.
public Display Display
{
get
{
return _display;
}
set
{
ValidatePlayerState(PlayerState.Idle);
if (value?.Owner != null)
{
if (ReferenceEquals(this, value.Owner))
{
return;
}
throw new ArgumentException("The display has already been assigned to another.");
}
SetDisplay(value).ThrowIfFailed("Failed to set the display to the player");
ReplaceDisplay(value);
}
}
PlayerErrorCode IDisplayable.ApplyEvasDisplay(DisplayType type, ElmSharp.EvasObject evasObject)
{
Debug.Assert(IsDisposed == false);
Debug.Assert(Enum.IsDefined(typeof(DisplayType), type));
Debug.Assert(type != DisplayType.None);
return NativeDisplay.SetDisplay(Handle,
type == DisplayType.Overlay ? PlayerDisplayType.Overlay : PlayerDisplayType.Evas, evasObject);
}
PlayerErrorCode IDisplayable.ApplyEcoreWindow(IntPtr windowHandle)
{
Debug.Assert(IsDisposed == false);
return NativeDisplay.SetEcoreDisplay(Handle, PlayerDisplayType.Overlay, windowHandle);
}
#endregion
private PlayerTrackInfo _audioTrack;
///
/// Gets the track info for the audio.
///
/// A for audio.
public PlayerTrackInfo AudioTrackInfo
{
get
{
if (_audioTrack == null)
{
_audioTrack = new PlayerTrackInfo(this, StreamType.Audio);
}
return _audioTrack;
}
}
private PlayerTrackInfo _subtitleTrackInfo;
///
/// Gets the track info for the subtitle.
///
/// A for the subtitle.
public PlayerTrackInfo SubtitleTrackInfo
{
get
{
if (_subtitleTrackInfo == null)
{
_subtitleTrackInfo = new PlayerTrackInfo(this, StreamType.Text);
}
return _subtitleTrackInfo;
}
}
private StreamInfo _streamInfo;
///
/// Gets the stream information.
///
/// A for this player.
public StreamInfo StreamInfo
{
get
{
if (_streamInfo == null)
{
_streamInfo = new StreamInfo(this);
}
return _streamInfo;
}
}
private readonly AudioEffect _audioEffect;
///
/// Gets the audio effect.
///
/// http://tizen.org/feature/multimedia.custom_audio_effect
/// The required feature is not supported.
public AudioEffect AudioEffect
{
get
{
if (_audioEffect == null)
{
throw new NotSupportedException($"The feature({Features.AudioEffect}) is not supported.");
}
return _audioEffect;
}
}
///
/// Gets or sets the mute state.
///
/// true if the player is muted; otherwise, false.
/// The player has already been disposed of.
public bool Muted
{
get
{
bool value = false;
NativePlayer.IsMuted(Handle, out value).ThrowIfFailed("Failed to get the mute state of the player");
Log.Info(PlayerLog.Tag, "get mute : " + value);
return value;
}
set
{
NativePlayer.SetMute(Handle, value).ThrowIfFailed("Failed to set the mute state of the player");
}
}
///
/// Gets or sets the current volume.
///
/// Valid volume range is from 0 to 1.0, inclusive.
/// The player has already been disposed of.
///
/// is less than zero.\n
/// -or-\n
/// is greater than 1.0.
///
public float Volume
{
get
{
float value = 0.0F;
NativePlayer.GetVolume(Handle, out value, out value).
ThrowIfFailed("Failed to get the volume of the player");
return value;
}
set
{
if (value < 0F || 1.0F < value)
{
throw new ArgumentOutOfRangeException(nameof(value), value,
$"Valid volume range is 0 <= value <= 1.0, but got { value }.");
}
NativePlayer.SetVolume(Handle, value, value).
ThrowIfFailed("Failed to set the volume of the player");
}
}
}
}