* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+using static Interop;
using System;
-using System.Threading.Tasks;
-using System.Runtime.InteropServices;
+using System.ComponentModel;
using System.Diagnostics;
-using System.IO;
-using System.Threading;
-using static Interop;
namespace Tizen.Multimedia
{
/// <summary>
/// Occurs when the playback of a media is finished.
/// </summary>
+ /// <since_tizen> 3 </since_tizen>
public event EventHandler<EventArgs> PlaybackCompleted;
private NativePlayer.PlaybackCompletedCallback _playbackCompletedCallback;
/// <summary>
/// Occurs when the playback of a media is interrupted.
/// </summary>
+ /// <remarks>
+ /// If the reason is <see cref="PlaybackInterruptionReason.ResourceConflict"/>,
+ /// the player state will be one of <see cref="PlayerState.Idle"/>, <see cref="PlayerState.Ready"/>,
+ /// or <see cref="PlayerState.Paused"/>.
+ /// </remarks>
+ /// <seealso cref="Player.State"/>
+ /// <since_tizen> 3 </since_tizen>
public event EventHandler<PlaybackInterruptedEventArgs> PlaybackInterrupted;
private NativePlayer.PlaybackInterruptedCallback _playbackInterruptedCallback;
/// Occurs when any error occurs.
/// </summary>
/// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <since_tizen> 3 </since_tizen>
public event EventHandler<PlayerErrorOccurredEventArgs> ErrorOccurred;
private NativePlayer.PlaybackErrorCallback _playbackErrorCallback;
/// Occurs when the video stream is changed.
/// </summary>
/// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <since_tizen> 3 </since_tizen>
public event EventHandler<VideoStreamChangedEventArgs> VideoStreamChanged;
private NativePlayer.VideoStreamChangedCallback _videoStreamChangedCallback;
/// Occurs when the subtitle is updated.
/// </summary>
/// <remarks>The event handler will be executed on an internal thread.</remarks>
+ /// <since_tizen> 3 </since_tizen>
public event EventHandler<SubtitleUpdatedEventArgs> SubtitleUpdated;
private NativePlayer.SubtitleUpdatedCallback _subtitleUpdatedCallback;
/// <summary>
/// Occurs when there is a change in the buffering status of streaming.
/// </summary>
+ /// <since_tizen> 3 </since_tizen>
public event EventHandler<BufferingProgressChangedEventArgs> BufferingProgressChanged;
private NativePlayer.BufferingProgressCallback _bufferingProgressCallback;
+ private NativePlayer.PrepareCallback _prepareCallback;
+
internal event EventHandler<MediaStreamBufferStatusChangedEventArgs> MediaStreamAudioBufferStatusChanged;
private NativePlayer.MediaStreamBufferStatusCallback _mediaStreamAudioBufferStatusChangedCallback;
internal event EventHandler<MediaStreamSeekingOccurredEventArgs> MediaStreamVideoSeekingOccurred;
private NativePlayer.MediaStreamSeekCallback _mediaStreamVideoSeekCallback;
- private bool _callbackRegistered;
-
private void RegisterEvents()
{
- if (_callbackRegistered)
- {
- return;
- }
RegisterSubtitleUpdatedCallback();
RegisterErrorOccurredCallback();
RegisterPlaybackInterruptedCallback();
RegisterMediaStreamBufferStatusCallback();
RegisterMediaStreamSeekCallback();
RegisterPlaybackCompletedCallback();
-
- _callbackRegistered = true;
}
private void RegisterSubtitleUpdatedCallback()
{
_subtitleUpdatedCallback = (duration, text, _) =>
{
- Log.Debug(PlayerLog.Tag, "duration : " + duration + ", text : " + text);
+ Log.Debug(PlayerLog.Tag, $"duration : {duration}, text : {text}");
SubtitleUpdated?.Invoke(this, new SubtitleUpdatedEventArgs(duration, text));
};
NativePlayer.SetSubtitleUpdatedCb(Handle, _subtitleUpdatedCallback).
- ThrowIfFailed("Failed to initialize the player");
+ ThrowIfFailed(this, "Failed to initialize the player");
}
private void RegisterPlaybackCompletedCallback()
PlaybackCompleted?.Invoke(this, EventArgs.Empty);
};
NativePlayer.SetCompletedCb(Handle, _playbackCompletedCallback).
- ThrowIfFailed("Failed to set PlaybackCompleted");
+ ThrowIfFailed(this, "Failed to set PlaybackCompleted");
}
private void RegisterPlaybackInterruptedCallback()
OnUnprepared();
}
- Log.Warn(PlayerLog.Tag, "interrupted reason : " + code);
+ Log.Warn(PlayerLog.Tag, $"interrupted reason : {code}");
PlaybackInterrupted?.Invoke(this, new PlaybackInterruptedEventArgs(code));
};
NativePlayer.SetInterruptedCb(Handle, _playbackInterruptedCallback).
- ThrowIfFailed("Failed to set PlaybackInterrupted");
+ ThrowIfFailed(this, "Failed to set PlaybackInterrupted");
}
private void RegisterErrorOccurredCallback()
};
NativePlayer.SetErrorCb(Handle, _playbackErrorCallback).
- ThrowIfFailed("Failed to set PlaybackError");
+ ThrowIfFailed(this, "Failed to set PlaybackError");
}
- #region VideoFrameDecoded event
-
- private EventHandler<VideoFrameDecodedEventArgs> _videoFrameDecoded;
-
- private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback;
+ /// <summary>
+ /// Raises the <see cref="ErrorOccurred"/> event.
+ /// </summary>
+ /// <param name="e">
+ /// An <see cref="PlayerErrorOccurredEventArgs"/> that contains the event data.
+ /// </param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected void OnErrorOccurred(PlayerErrorOccurredEventArgs e)
+ {
+ ErrorOccurred?.Invoke(this, e);
+ }
+ #region VideoFrameDecoded event
/// <summary>
/// Occurs when a video frame is decoded.
/// </summary>
/// <feature>http://tizen.org/feature/multimedia.raw_video</feature>
/// <exception cref="NotSupportedException">The required feature is not supported.</exception>
/// <seealso cref="VideoFrameDecodedEventArgs.Packet"/>
- public event EventHandler<VideoFrameDecodedEventArgs> VideoFrameDecoded
- {
- add
- {
- ValidationUtil.ValidateFeatureSupported(Features.RawVideo);
-
- _videoFrameDecoded += value;
- }
- remove
- {
- ValidationUtil.ValidateFeatureSupported(Features.RawVideo);
-
- _videoFrameDecoded -= value;
- }
- }
+ /// <since_tizen> 3 </since_tizen>
+ public event EventHandler<VideoFrameDecodedEventArgs> VideoFrameDecoded;
+ private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback;
+ #endregion
- private void RegisterVideoFrameDecodedCallback()
- {
- _videoFrameDecodedCallback = (packetHandle, _) =>
- {
- var handler = _videoFrameDecoded;
- if (handler != null)
- {
- Log.Debug(PlayerLog.Tag, "packet : " + packetHandle);
- handler.Invoke(this,
- new VideoFrameDecodedEventArgs(MediaPacket.From(packetHandle)));
- }
- else
- {
- MediaPacket.From(packetHandle).Dispose();
- }
- };
+ #region AudioFrameDecoded event
+ /// <summary>
+ /// Occurs when a audio frame is decoded.
+ /// </summary>
+ /// <remarks>
+ /// <para>The event handler will be executed on an internal thread.</para>
+ /// <para>The <see cref="AudioDataDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
+ /// </remarks>
+ /// <seealso cref="AudioDataDecodedEventArgs.Packet"/>
+ /// <since_tizen> 6 </since_tizen>
+ public event EventHandler<AudioDataDecodedEventArgs> AudioDataDecoded;
- NativePlayer.SetVideoFrameDecodedCb(Handle, _videoFrameDecodedCallback).
- ThrowIfFailed("Failed to register the VideoFrameDecoded");
- }
+ private NativePlayer.AudioFrameDecodedCallback _audioFrameDecodedCallback;
#endregion
private void RegisterVideoStreamChangedCallback()
{
- ValidatePlayerState(PlayerState.Idle);
-
_videoStreamChangedCallback = (width, height, fps, bitrate, _) =>
{
- Log.Debug(PlayerLog.Tag, "height : " + height + ", width : " + width
- + ", fps : " + fps + ", bitrate : " + bitrate);
+ Log.Debug(PlayerLog.Tag, $"height={height}, width={width}, fps={fps}, bitrate={bitrate}");
VideoStreamChanged?.Invoke(this, new VideoStreamChangedEventArgs(height, width, fps, bitrate));
};
NativePlayer.SetVideoStreamChangedCb(Handle, _videoStreamChangedCallback).
- ThrowIfFailed("Failed to set the video stream changed callback");
+ ThrowIfFailed(this, "Failed to set the video stream changed callback");
}
private void RegisterBufferingCallback()
_bufferingProgressCallback = (percent, _) =>
{
Log.Debug(PlayerLog.Tag, $"Buffering callback with percent { percent }");
+
BufferingProgressChanged?.Invoke(this, new BufferingProgressChangedEventArgs(percent));
};
NativePlayer.SetBufferingCb(Handle, _bufferingProgressCallback).
- ThrowIfFailed("Failed to set BufferingProgress");
+ ThrowIfFailed(this, "Failed to set BufferingProgress");
}
private void RegisterMediaStreamBufferStatusCallback()
{
Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
Log.Debug(PlayerLog.Tag, "audio buffer status : " + status);
+
MediaStreamAudioBufferStatusChanged?.Invoke(this,
new MediaStreamBufferStatusChangedEventArgs(status));
};
{
Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
Log.Debug(PlayerLog.Tag, "video buffer status : " + status);
+
MediaStreamVideoBufferStatusChanged?.Invoke(this,
new MediaStreamBufferStatusChangedEventArgs(status));
};
NativePlayer.MediaStreamBufferStatusCallback cb)
{
NativePlayer.SetMediaStreamBufferStatusCb(Handle, streamType, cb).
- ThrowIfFailed("Failed to SetMediaStreamBufferStatus");
+ ThrowIfFailed(this, "Failed to SetMediaStreamBufferStatus");
}
private void RegisterMediaStreamSeekCallback()
private void RegisterMediaStreamSeekCallback(StreamType streamType, NativePlayer.MediaStreamSeekCallback cb)
{
NativePlayer.SetMediaStreamSeekCb(Handle, streamType, cb).
- ThrowIfFailed("Failed to SetMediaStreamSeek");
+ ThrowIfFailed(this, "Failed to SetMediaStreamSeek");
}
}
}