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
175 /// Occurs when a video frame is decoded.
178 /// <para>The event handler will be executed on an internal thread.</para>
179 /// <para>The <see cref="VideoFrameDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
181 /// <feature>http://tizen.org/feature/multimedia.raw_video</feature>
182 /// <exception cref="NotSupportedException">The required feature is not supported.</exception>
183 /// <seealso cref="VideoFrameDecodedEventArgs.Packet"/>
184 /// <since_tizen> 3 </since_tizen>
185 public event EventHandler<VideoFrameDecodedEventArgs> VideoFrameDecoded;
186 private NativePlayer.VideoFrameDecodedCallback _videoFrameDecodedCallback;
189 #region AudioFrameDecoded event
191 /// Occurs when a audio frame is decoded.
194 /// <para>The event handler will be executed on an internal thread.</para>
195 /// <para>The <see cref="AudioDataDecodedEventArgs.Packet"/> in event args should be disposed after use.</para>
197 /// <seealso cref="AudioDataDecodedEventArgs.Packet"/>
198 /// <since_tizen> 6 </since_tizen>
199 public event EventHandler<AudioDataDecodedEventArgs> AudioDataDecoded;
201 private NativePlayer.AudioFrameDecodedCallback _audioFrameDecodedCallback;
204 private void RegisterVideoStreamChangedCallback()
206 _videoStreamChangedCallback = (width, height, fps, bitrate, _) =>
208 Log.Debug(PlayerLog.Tag, $"height={height}, width={width}, fps={fps}, bitrate={bitrate}");
210 VideoStreamChanged?.Invoke(this, new VideoStreamChangedEventArgs(height, width, fps, bitrate));
213 NativePlayer.SetVideoStreamChangedCb(Handle, _videoStreamChangedCallback).
214 ThrowIfFailed(this, "Failed to set the video stream changed callback");
217 private void RegisterBufferingCallback()
219 _bufferingProgressCallback = (percent, _) =>
221 Log.Debug(PlayerLog.Tag, $"Buffering callback with percent { percent }");
223 BufferingProgressChanged?.Invoke(this, new BufferingProgressChangedEventArgs(percent));
226 NativePlayer.SetBufferingCb(Handle, _bufferingProgressCallback).
227 ThrowIfFailed(this, "Failed to set BufferingProgress");
230 private void RegisterMediaStreamBufferStatusCallback()
232 _mediaStreamAudioBufferStatusChangedCallback = (status, _) =>
234 Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
235 Log.Debug(PlayerLog.Tag, "audio buffer status : " + status);
237 MediaStreamAudioBufferStatusChanged?.Invoke(this,
238 new MediaStreamBufferStatusChangedEventArgs(status));
240 _mediaStreamVideoBufferStatusChangedCallback = (status, _) =>
242 Debug.Assert(Enum.IsDefined(typeof(MediaStreamBufferStatus), status));
243 Log.Debug(PlayerLog.Tag, "video buffer status : " + status);
245 MediaStreamVideoBufferStatusChanged?.Invoke(this,
246 new MediaStreamBufferStatusChangedEventArgs(status));
249 RegisterMediaStreamBufferStatusCallback(StreamType.Audio, _mediaStreamAudioBufferStatusChangedCallback);
250 RegisterMediaStreamBufferStatusCallback(StreamType.Video, _mediaStreamVideoBufferStatusChangedCallback);
253 private void RegisterMediaStreamBufferStatusCallback(StreamType streamType,
254 NativePlayer.MediaStreamBufferStatusCallback cb)
256 NativePlayer.SetMediaStreamBufferStatusCb(Handle, streamType, cb).
257 ThrowIfFailed(this, "Failed to SetMediaStreamBufferStatus");
260 private void RegisterMediaStreamSeekCallback()
262 _mediaStreamAudioSeekCallback = (offset, _) =>
264 Log.Debug(PlayerLog.Tag, "audio seeking offset : " + offset);
265 MediaStreamAudioSeekingOccurred?.Invoke(this, new MediaStreamSeekingOccurredEventArgs(offset));
267 _mediaStreamVideoSeekCallback = (offset, _) =>
269 Log.Debug(PlayerLog.Tag, "video seeking offset : " + offset);
270 MediaStreamVideoSeekingOccurred?.Invoke(this, new MediaStreamSeekingOccurredEventArgs(offset));
273 RegisterMediaStreamSeekCallback(StreamType.Audio, _mediaStreamAudioSeekCallback);
274 RegisterMediaStreamSeekCallback(StreamType.Video, _mediaStreamVideoSeekCallback);
277 private void RegisterMediaStreamSeekCallback(StreamType streamType, NativePlayer.MediaStreamSeekCallback cb)
279 NativePlayer.SetMediaStreamSeekCb(Handle, streamType, cb).
280 ThrowIfFailed(this, "Failed to SetMediaStreamSeek");