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.
19 using System.ComponentModel;
20 using System.Diagnostics;
22 namespace Tizen.Multimedia
24 public partial class Player
27 /// Occurs when the playback of a media is finished.
29 /// <since_tizen> 3 </since_tizen>
30 public event EventHandler<EventArgs> PlaybackCompleted;
31 private NativePlayer.PlaybackCompletedCallback _playbackCompletedCallback;
34 /// Occurs when the playback of a media is interrupted.
37 /// If the reason is <see cref="PlaybackInterruptionReason.ResourceConflict"/>,
38 /// the player state will be one of <see cref="PlayerState.Idle"/>, <see cref="PlayerState.Ready"/>,
39 /// or <see cref="PlayerState.Paused"/>.
41 /// <seealso cref="Player.State"/>
42 /// <since_tizen> 3 </since_tizen>
43 public event EventHandler<PlaybackInterruptedEventArgs> PlaybackInterrupted;
44 private NativePlayer.PlaybackInterruptedCallback _playbackInterruptedCallback;
47 /// Occurs when any error occurs.
49 /// <remarks>The event handler will be executed on an internal thread.</remarks>
50 /// <since_tizen> 3 </since_tizen>
51 public event EventHandler<PlayerErrorOccurredEventArgs> ErrorOccurred;
52 private NativePlayer.PlaybackErrorCallback _playbackErrorCallback;
55 /// Occurs when the video stream is changed.
57 /// <remarks>The event handler will be executed on an internal thread.</remarks>
58 /// <since_tizen> 3 </since_tizen>
59 public event EventHandler<VideoStreamChangedEventArgs> VideoStreamChanged;
60 private NativePlayer.VideoStreamChangedCallback _videoStreamChangedCallback;
63 /// Occurs when the subtitle is updated.
65 /// <remarks>The event handler will be executed on an internal thread.</remarks>
66 /// <since_tizen> 3 </since_tizen>
67 public event EventHandler<SubtitleUpdatedEventArgs> SubtitleUpdated;
68 private NativePlayer.SubtitleUpdatedCallback _subtitleUpdatedCallback;
71 /// Occurs when there is a change in the buffering status of streaming.
73 /// <since_tizen> 3 </since_tizen>
74 public event EventHandler<BufferingProgressChangedEventArgs> BufferingProgressChanged;
75 private NativePlayer.BufferingProgressCallback _bufferingProgressCallback;
77 private NativePlayer.PrepareCallback _prepareCallback;
79 internal event EventHandler<MediaStreamBufferStatusChangedEventArgs> MediaStreamAudioBufferStatusChanged;
80 private NativePlayer.MediaStreamBufferStatusCallback _mediaStreamAudioBufferStatusChangedCallback;
82 internal event EventHandler<MediaStreamBufferStatusChangedEventArgs> MediaStreamVideoBufferStatusChanged;
83 private NativePlayer.MediaStreamBufferStatusCallback _mediaStreamVideoBufferStatusChangedCallback;
85 internal event EventHandler<MediaStreamSeekingOccurredEventArgs> MediaStreamAudioSeekingOccurred;
86 private NativePlayer.MediaStreamSeekCallback _mediaStreamAudioSeekCallback;
88 internal event EventHandler<MediaStreamSeekingOccurredEventArgs> MediaStreamVideoSeekingOccurred;
89 private NativePlayer.MediaStreamSeekCallback _mediaStreamVideoSeekCallback;
91 private void RegisterEvents()
93 RegisterSubtitleUpdatedCallback();
94 RegisterErrorOccurredCallback();
95 RegisterPlaybackInterruptedCallback();
96 RegisterVideoStreamChangedCallback();
97 RegisterBufferingCallback();
98 RegisterMediaStreamBufferStatusCallback();
99 RegisterMediaStreamSeekCallback();
100 RegisterPlaybackCompletedCallback();
103 private void RegisterSubtitleUpdatedCallback()
105 _subtitleUpdatedCallback = (duration, text, _) =>
107 Log.Debug(PlayerLog.Tag, $"duration : {duration}, text : {text}");
108 SubtitleUpdated?.Invoke(this, new SubtitleUpdatedEventArgs(duration, text));
111 NativePlayer.SetSubtitleUpdatedCb(Handle, _subtitleUpdatedCallback).
112 ThrowIfFailed(this, "Failed to initialize the player");
115 private void RegisterPlaybackCompletedCallback()
117 _playbackCompletedCallback = _ =>
119 Log.Debug(PlayerLog.Tag, "completed callback");
120 PlaybackCompleted?.Invoke(this, EventArgs.Empty);
122 NativePlayer.SetCompletedCb(Handle, _playbackCompletedCallback).
123 ThrowIfFailed(this, "Failed to set PlaybackCompleted");
126 private void RegisterPlaybackInterruptedCallback()
128 _playbackInterruptedCallback = (code, _) =>
130 if (!Enum.IsDefined(typeof(PlaybackInterruptionReason), code))
135 if (code == PlaybackInterruptionReason.ResourceConflict)
140 Log.Warn(PlayerLog.Tag, $"interrupted reason : {code}");
141 PlaybackInterrupted?.Invoke(this, new PlaybackInterruptedEventArgs(code));
144 NativePlayer.SetInterruptedCb(Handle, _playbackInterruptedCallback).
145 ThrowIfFailed(this, "Failed to set PlaybackInterrupted");
148 private void RegisterErrorOccurredCallback()
150 _playbackErrorCallback = (code, _) =>
152 //TODO handle service disconnected error.
153 Log.Warn(PlayerLog.Tag, "error code : " + code);
154 ErrorOccurred?.Invoke(this, new PlayerErrorOccurredEventArgs((PlayerError)code));
157 NativePlayer.SetErrorCb(Handle, _playbackErrorCallback).
158 ThrowIfFailed(this, "Failed to set PlaybackError");
162 /// Raises the <see cref="ErrorOccurred"/> event.
165 /// An <see cref="PlayerErrorOccurredEventArgs"/> that contains the event data.
167 [EditorBrowsable(EditorBrowsableState.Never)]
168 protected void OnErrorOccurred(PlayerErrorOccurredEventArgs e)
170 ErrorOccurred?.Invoke(this, e);
173 #region VideoFrameDecoded event
174 private EventHandler<VideoFrameDecodedEventArgs> _videoFrameDecoded;
176 private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback;
179 /// Occurs when a video frame is decoded.
182 /// <para>The event handler will be executed on an internal thread.</para>
183 /// <para>The <see cref="VideoFrameDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
185 /// <feature>http://tizen.org/feature/multimedia.raw_video</feature>
186 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
187 /// <seealso cref="VideoFrameDecodedEventArgs.Packet"/>
188 /// <since_tizen> 3 </since_tizen>
189 public event EventHandler<VideoFrameDecodedEventArgs> VideoFrameDecoded
193 ValidationUtil.ValidateFeatureSupported(PlayerFeatures.RawVideo);
195 _videoFrameDecoded += value;
199 ValidationUtil.ValidateFeatureSupported(PlayerFeatures.RawVideo);
201 _videoFrameDecoded -= value;
205 private void RegisterVideoFrameDecodedCallback()
207 _videoFrameDecodedCallback = (packetHandle, _) =>
209 var handler = _videoFrameDecoded;
212 Log.Debug(PlayerLog.Tag, "packet : " + packetHandle);
214 new VideoFrameDecodedEventArgs(MediaPacket.From(packetHandle)));
218 MediaPacket.From(packetHandle).Dispose();
222 NativePlayer.SetVideoFrameDecodedCb(Handle, _videoFrameDecodedCallback).
223 ThrowIfFailed(this, "Failed to register the VideoFrameDecoded");
227 #region AudioFrameDecoded event
229 /// Occurs when a audio frame is decoded.
232 /// <para>The event handler will be executed on an internal thread.</para>
233 /// <para>The <see cref="AudioDataDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
235 /// <seealso cref="AudioDataDecodedEventArgs.Packet"/>
236 /// <since_tizen> 6 </since_tizen>
237 public event EventHandler<AudioDataDecodedEventArgs> AudioDataDecoded;
239 private NativePlayer.AudioFrameDecodedCallback _audioFrameDecodedCallback;
242 private void RegisterVideoStreamChangedCallback()
244 _videoStreamChangedCallback = (width, height, fps, bitrate, _) =>
246 Log.Debug(PlayerLog.Tag, $"height={height}, width={width}, fps={fps}, bitrate={bitrate}");
248 VideoStreamChanged?.Invoke(this, new VideoStreamChangedEventArgs(height, width, fps, bitrate));
251 NativePlayer.SetVideoStreamChangedCb(Handle, _videoStreamChangedCallback).
252 ThrowIfFailed(this, "Failed to set the video stream changed callback");
255 private void RegisterBufferingCallback()
257 _bufferingProgressCallback = (percent, _) =>
259 Log.Debug(PlayerLog.Tag, $"Buffering callback with percent { percent }");
261 BufferingProgressChanged?.Invoke(this, new BufferingProgressChangedEventArgs(percent));
264 NativePlayer.SetBufferingCb(Handle, _bufferingProgressCallback).
265 ThrowIfFailed(this, "Failed to set BufferingProgress");
268 private void RegisterMediaStreamBufferStatusCallback()
270 _mediaStreamAudioBufferStatusChangedCallback = (status, _) =>
272 Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
273 Log.Debug(PlayerLog.Tag, "audio buffer status : " + status);
275 MediaStreamAudioBufferStatusChanged?.Invoke(this,
276 new MediaStreamBufferStatusChangedEventArgs(status));
278 _mediaStreamVideoBufferStatusChangedCallback = (status, _) =>
280 Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
281 Log.Debug(PlayerLog.Tag, "video buffer status : " + status);
283 MediaStreamVideoBufferStatusChanged?.Invoke(this,
284 new MediaStreamBufferStatusChangedEventArgs(status));
287 RegisterMediaStreamBufferStatusCallback(StreamType.Audio, _mediaStreamAudioBufferStatusChangedCallback);
288 RegisterMediaStreamBufferStatusCallback(StreamType.Video, _mediaStreamVideoBufferStatusChangedCallback);
291 private void RegisterMediaStreamBufferStatusCallback(StreamType streamType,
292 NativePlayer.MediaStreamBufferStatusCallback cb)
294 NativePlayer.SetMediaStreamBufferStatusCb(Handle, streamType, cb).
295 ThrowIfFailed(this, "Failed to SetMediaStreamBufferStatus");
298 private void RegisterMediaStreamSeekCallback()
300 _mediaStreamAudioSeekCallback = (offset, _) =>
302 Log.Debug(PlayerLog.Tag, "audio seeking offset : " + offset);
303 MediaStreamAudioSeekingOccurred?.Invoke(this, new MediaStreamSeekingOccurredEventArgs(offset));
305 _mediaStreamVideoSeekCallback = (offset, _) =>
307 Log.Debug(PlayerLog.Tag, "video seeking offset : " + offset);
308 MediaStreamVideoSeekingOccurred?.Invoke(this, new MediaStreamSeekingOccurredEventArgs(offset));
311 RegisterMediaStreamSeekCallback(StreamType.Audio, _mediaStreamAudioSeekCallback);
312 RegisterMediaStreamSeekCallback(StreamType.Video, _mediaStreamVideoSeekCallback);
315 private void RegisterMediaStreamSeekCallback(StreamType streamType, NativePlayer.MediaStreamSeekCallback cb)
317 NativePlayer.SetMediaStreamSeekCb(Handle, streamType, cb).
318 ThrowIfFailed(this, "Failed to SetMediaStreamSeek");