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.
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using Tizen.Internals.Errors;
21 using Native = Interop.StreamRecorder;
23 namespace Tizen.Multimedia
25 static internal class StreamRecorderLog
27 internal const string Tag = "Tizen.Multimedia.StreamRecorder";
31 /// Provides methods to control stream recorder.
34 /// StreamRecorder class provides functions to record raw image frame
35 /// also provides recording start, stop and save the content etc.
37 public class StreamRecorder : IDisposable
39 private IntPtr _handle;
40 private bool _disposed = false;
42 /// Occurred when recording is progressing for recording status.
44 private EventHandler<RecordingProgressEventArgs> _recordingStatusChanged;
45 private Native.RecordingStatusCallback _recordingStatusCallback;
47 /// Occurred when recording time or size reach limit.
49 private EventHandler<StreamRecordingLimitReachedEventArgs> _recordingLimitReached;
50 private Native.RecordingLimitReachedCallback _recordingLimitReachedCallback;
52 /// Occurred when streamrecorder complete to use pushed buffer.
54 private EventHandler<StreamRecordingBufferConsumedEventArgs> _bufferConsumed;
55 private Native.BufferConsumedCallback _bufferConsumedCallback;
57 /// Occurred when streamrecorder state is changed.
59 private EventHandler<StreamRecorderNotifiedEventArgs> _recorderNotified;
60 private Native.NotifiedCallback _notifiedCallback;
62 /// Occurred when error is occured.
64 private EventHandler<StreamRecordingErrorOccurredEventArgs> _recordingErrorOccurred;
65 private Native.RecorderErrorCallback _recorderErrorCallback;
67 private List<StreamRecorderFileFormat> _formats;
68 private List<StreamRecorderAudioCodec> _audioCodec;
69 private List<StreamRecorderVideoCodec> _videoCodec;
70 private List<StreamRecorderVideoResolution> _resolutions;
71 StreamRecorderVideoResolution _videoResolution = null;
74 /// Stream recorder constructor.
76 public StreamRecorder()
78 int ret = Native.Create(out _handle);
79 if (ret != (int)StreamRecorderError.None)
81 StreamRecorderErrorFactory.ThrowException(ret, "Failed to create stream recorder");
83 _formats = new List<StreamRecorderFileFormat>();
84 _audioCodec = new List<StreamRecorderAudioCodec>();
85 _videoCodec = new List<StreamRecorderVideoCodec>();
86 _resolutions = new List<StreamRecorderVideoResolution>();
87 _videoResolution = new StreamRecorderVideoResolution(_handle);
91 /// Stream recorder destructor.
99 /// Event that occurs when streamrecorder state is changed.
101 public event EventHandler<StreamRecorderNotifiedEventArgs> RecorderNotified
105 if (_recorderNotified == null)
107 RegisterStreamRecorderNotifiedEvent();
109 _recorderNotified += value;
113 _recorderNotified -= value;
114 if (_recorderNotified == null)
116 UnregisterStreamRecorderNotifiedEvent();
122 /// Event that occurs when buffer had comsumed completely.
124 public event EventHandler<StreamRecordingBufferConsumedEventArgs> BufferConsumed
128 if (_bufferConsumed == null)
130 RegisterBufferComsumedEvent();
132 _bufferConsumed += value;
136 _bufferConsumed -= value;
137 if (_bufferConsumed == null)
139 UnregisterBufferComsumedEvent();
145 /// Event that occurs when recording status changed.
147 public event EventHandler<RecordingProgressEventArgs> RecordingStatusChanged
151 if (_recordingStatusChanged == null)
153 RegisterRecordingStatusChangedEvent();
155 _recordingStatusChanged += value;
159 _recordingStatusChanged -= value;
160 if (_recordingStatusChanged == null)
162 UnregisterRecordingStatusChangedEvent();
168 /// Event that occurs when recording limit is reached.
170 public event EventHandler<StreamRecordingLimitReachedEventArgs> RecordingLimitReached
174 if (_recordingLimitReached == null)
176 RegisterRecordingLimitReachedEvent();
178 _recordingLimitReached += value;
182 _recordingLimitReached -= value;
183 if (_recordingLimitReached == null)
185 UnregisterRecordingLimitReachedEvent();
191 /// Event that occurs when an error occured during recorder operation.
193 public event EventHandler<StreamRecordingErrorOccurredEventArgs> RecordingErrorOccurred
197 if (_recordingErrorOccurred == null)
199 RegisterRecordingErrorOccurredEvent();
201 _recordingErrorOccurred += value;
205 _recordingErrorOccurred -= value;
206 if (_recordingErrorOccurred == null)
208 UnregisterRecordingErrorOccurredEvent();
214 /// The file path to record.
217 /// If the same file already exists in the file system, then old file
218 /// will be overwritten.
220 public string FilePath
225 int ret = Native.GetFileName(_handle, out val);
226 if ((StreamRecorderError)ret != StreamRecorderError.None)
228 Log.Error(StreamRecorderLog.Tag, "Failed to get filepath, " + (StreamRecorderError)ret);
230 string result = Marshal.PtrToStringAnsi(val);
231 LibcSupport.Free(val);
236 int ret = Native.SetFileName(_handle, value);
237 if ((StreamRecorderError)ret != StreamRecorderError.None)
239 Log.Error(StreamRecorderLog.Tag, "Failed to set filepath, " + (StreamRecorderError)ret);
240 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set filepath");
246 /// Get the current state of the stream recorder.
248 /// <value> The current state of stream recorder.
249 public StreamRecorderState State
255 int ret = Native.GetState(_handle, out val);
256 if ((StreamRecorderError)ret != StreamRecorderError.None)
258 Log.Error(StreamRecorderLog.Tag, "Failed to get stream recorder state, " + (StreamRecorderError)ret);
260 return (StreamRecorderState)val;
265 /// Get/Set the file format for recording media stream.
268 /// Must set <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>.
269 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
271 /// <exception cref="ArgumentException">The format does not valid.</exception>
272 /// <seealso cref="SupportedFileFormats"/>
273 public StreamRecorderFileFormat FileFormat
279 int ret = Native.GetFileFormat(_handle, out val);
280 if ((StreamRecorderError)ret != StreamRecorderError.None)
282 Log.Error(StreamRecorderLog.Tag, "Failed to get file format, " + (StreamRecorderError)ret);
284 return (StreamRecorderFileFormat)val;
288 int ret = Native.SetFileFormat(_handle, (int)value);
289 if ((StreamRecorderError)ret != StreamRecorderError.None)
291 Log.Error(StreamRecorderLog.Tag, "Failed to set file format, " + (StreamRecorderError)ret);
292 StreamRecorderErrorFactory.ThrowException(ret);
298 /// The audio codec for encoding an audio stream.
301 /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
302 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
304 /// <exception cref="ArgumentException">The codec does not valid.</exception>
305 /// <seealso cref="SupportedAudioEncodings"/>
306 public StreamRecorderAudioCodec AudioCodec
312 int ret = Native.GetAudioEncoder(_handle, out val);
313 if ((StreamRecorderError)ret != StreamRecorderError.None)
315 Log.Error(StreamRecorderLog.Tag, "Failed to get audio codec, " + (StreamRecorderError)ret);
317 return (StreamRecorderAudioCodec)val;
321 int ret = Native.SetAudioEncoder(_handle, (int)value);
322 if ((StreamRecorderError)ret != StreamRecorderError.None)
324 Log.Error(StreamRecorderLog.Tag, "Failed to set audio codec, " + (StreamRecorderError)ret);
325 StreamRecorderErrorFactory.ThrowException(ret);
331 /// The video codec for encoding video stream.
334 /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
335 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
337 /// <exception cref="ArgumentException">The codec does not valid.</exception>
338 /// <seealso cref="SupportedVideoEncodings"/>
339 public StreamRecorderVideoCodec VideoCodec
345 int ret = Native.GetVideoEncoder(_handle, out val);
346 if ((StreamRecorderError)ret != StreamRecorderError.None)
348 Log.Error(StreamRecorderLog.Tag, "Failed to get video codec, " + (StreamRecorderError)ret);
350 return (StreamRecorderVideoCodec)val;
354 int ret = Native.SetVideoEncoder(_handle, (int)value);
356 if ((StreamRecorderError)ret != StreamRecorderError.None)
358 Log.Error(StreamRecorderLog.Tag, "Failed to set video codec, " + (StreamRecorderError)ret);
359 StreamRecorderErrorFactory.ThrowException(ret);
365 /// The maximum size of a recording file in KB(kilobytes). If 0, means
366 /// unlimited recording size.
369 /// After reaching the limitation, the data which is being recorded will
370 /// be discarded and not written to the file.
371 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
373 /// <exception cref="ArgumentException">The value set to below 0.</exception>
374 /// <seealso cref="StreamRecordingLimitReachedEventArgs"/>
381 int ret = Native.GetRecordingLimit(_handle, 1, out val);
382 if ((StreamRecorderError)ret != StreamRecorderError.None)
384 Log.Error(StreamRecorderLog.Tag, "Failed to get size limit, " + (StreamRecorderError)ret);
390 int ret = Native.SetRecordingLimit(_handle, 1, value);
391 if ((StreamRecorderError)ret != StreamRecorderError.None)
393 Log.Error(StreamRecorderLog.Tag, "Failed to set sizelimit, " + (StreamRecorderError)ret);
394 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set size limit");
400 /// The time limit of a recording file in Seconds. If 0, means unlimited recording
404 /// After reaching the limitation, the data which is being recorded will
405 /// be discarded and not written to the file.
406 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
408 /// <exception cref="ArgumentException">The value set to below 0.</exception>
409 /// <seealso cref="StreamRecordingLimitReachedEventArgs"/>
416 int ret = Native.GetRecordingLimit(_handle, 0, out val);
417 if ((StreamRecorderError)ret != StreamRecorderError.None)
419 Log.Error(StreamRecorderLog.Tag, "Failed to get time limit, " + (StreamRecorderError)ret);
425 int ret = Native.SetRecordingLimit(_handle, 0, value);
426 if ((StreamRecorderError)ret != StreamRecorderError.None)
428 Log.Error(StreamRecorderLog.Tag, "Failed to set timelimit, " + (StreamRecorderError)ret);
429 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set time limit");
435 /// The sampling rate of an audio stream in hertz.
438 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
439 /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
440 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>.
442 /// <exception cref="ArgumentException">The value set to below 0.</exception>
443 public int AudioSampleRate
449 int ret = Native.GetAudioSampleRate(_handle, out val);
450 if ((StreamRecorderError)ret != StreamRecorderError.None)
452 Log.Error(StreamRecorderLog.Tag, "Failed to get audio samplerate, " + (StreamRecorderError)ret);
458 int ret = Native.SetAudioSampleRate(_handle, value);
459 if ((StreamRecorderError)ret != StreamRecorderError.None)
461 Log.Error(StreamRecorderLog.Tag, "Failed to set audio samplerate, " + (StreamRecorderError)ret);
462 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio samplerate");
468 /// The bitrate of an audio encoder in bits per second.
471 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
472 /// Must set <see cref="StreamRecorderSourceType.Audio"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
473 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
475 /// <exception cref="ArgumentException">The value set to below 0.</exception>
476 public int AudioBitRate
482 int ret = Native.GetAudioEncoderBitrate(_handle, out val);
483 if ((StreamRecorderError)ret != StreamRecorderError.None)
485 Log.Error(StreamRecorderLog.Tag, "Failed to get audio bitrate, " + (StreamRecorderError)ret);
491 int ret = Native.SetAudioEncoderBitrate(_handle, value);
492 if ((StreamRecorderError)ret != StreamRecorderError.None)
494 Log.Error(StreamRecorderLog.Tag, "Failed to set audio bitrate, " + (StreamRecorderError)ret);
495 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio bitrate");
501 /// The bitrate of an video encoder in bits per second.
504 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
505 /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
506 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
508 /// <exception cref="ArgumentException">The value set to below 0.</exception>
509 public int VideoBitRate
515 int ret = Native.GetVideoEncoderBitrate(_handle, out val);
516 if ((StreamRecorderError)ret != StreamRecorderError.None)
518 Log.Error(StreamRecorderLog.Tag, "Failed to get video bitrate, " + (StreamRecorderError)ret);
524 int ret = Native.SetVideoEncoderBitrate(_handle, value);
525 if ((StreamRecorderError)ret != StreamRecorderError.None)
527 Log.Error(StreamRecorderLog.Tag, "Failed to set video bitrate, " + (StreamRecorderError)ret);
528 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set video bitrate");
534 /// The video frame rate for recording media stream.
537 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
538 /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
539 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
541 /// <exception cref="NotSupportedException">The value set to below 0.</exception>
542 public int VideoFrameRate
548 int ret = Native.GetVideoFramerate(_handle, out val);
549 if ((StreamRecorderError)ret != StreamRecorderError.None)
551 Log.Error(StreamRecorderLog.Tag, "Failed to get video framerate, " + (StreamRecorderError)ret);
557 int ret = Native.SetVideoFramerate(_handle, value);
558 if ((StreamRecorderError)ret != StreamRecorderError.None)
560 Log.Error(StreamRecorderLog.Tag, "Failed to set video framerate, " + (StreamRecorderError)ret);
561 StreamRecorderErrorFactory.ThrowException(ret);
567 /// Get or Set the video source format for recording media stream.
569 /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
570 /// <seealso cref="StreamRecorderVideoSourceFormat"/>
571 public StreamRecorderVideoSourceFormat VideoSourceFormat
577 int ret = Native.GetVideoSourceFormat(_handle, out val);
578 if ((StreamRecorderError)ret != StreamRecorderError.None)
580 Log.Error(StreamRecorderLog.Tag, "Failed to get video framerate, " + (StreamRecorderError)ret);
582 return (StreamRecorderVideoSourceFormat)val;
586 int ret = Native.SetVideoSourceFormat(_handle, (int)value);
587 if ((StreamRecorderError)ret != StreamRecorderError.None)
589 Log.Error(StreamRecorderLog.Tag, "Failed to set video framerate, " + (StreamRecorderError)ret);
590 StreamRecorderErrorFactory.ThrowException(ret);
596 /// The number of audio channel.
599 /// The attribute is applied only in Created state.
600 /// For mono recording, set channel to 1.
601 /// For stereo recording, set channel to 2.
602 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
604 /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
605 public int AudioChannel
611 int ret = Native.GetAudioChannel(_handle, out val);
612 if ((StreamRecorderError)ret != StreamRecorderError.None)
614 Log.Error(StreamRecorderLog.Tag, "Failed to get audio channel, " + (StreamRecorderError)ret);
620 int ret = Native.SetAudioChannel(_handle, value);
621 if ((StreamRecorderError)ret != StreamRecorderError.None)
623 Log.Error(StreamRecorderLog.Tag, "Failed to set audio channel, " + (StreamRecorderError)ret);
624 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set audio channel");
630 /// Video resolution of the video recording.
633 /// Must set <see cref="StreamRecorderSourceType.Video"/> or <see cref="StreamRecorderSourceType.VideoAudio"/>
634 /// by <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>
635 /// The recorder state must be <see cref="StreamRecorderState.Created"/> state.
637 /// <exception cref="ArgumentException">The value set to a invalid value.</exception>
638 /// <seealso cref="SupportedVideoResolutions"/>
639 public StreamRecorderVideoResolution Resolution
643 return _videoResolution;
648 /// Retrieves all the file formats supported by the stream recorder.
651 /// It returns a list containing all the supported file
652 /// formats by Stream recorder.
654 /// <seealso cref="StreamRecorderFileFormat"/>
655 public IEnumerable<StreamRecorderFileFormat> SupportedFileFormats
659 if (_formats.Count == 0)
661 Native.FileFormatCallback callback = (StreamRecorderFileFormat format, IntPtr userData) =>
663 _formats.Add(format);
666 int ret = Native.FileFormats(_handle, callback, IntPtr.Zero);
667 if (ret != (int)StreamRecorderError.None)
669 StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported fileformats");
677 /// Retrieves all the audio encoders supported by the recorder.
680 /// It returns a list containing all the supported audio encoders
683 /// <seealso cref="StreamRecorderAudioCodec"/>
684 public IEnumerable<StreamRecorderAudioCodec> SupportedAudioEncodings
688 if (_audioCodec.Count == 0)
690 Native.AudioEncoderCallback callback = (StreamRecorderAudioCodec codec, IntPtr userData) =>
692 _audioCodec.Add(codec);
695 int ret = Native.AudioEncoders(_handle, callback, IntPtr.Zero);
696 if (ret != (int)StreamRecorderError.None)
698 StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported audio encoders");
706 /// Retrieves all the video encoders supported by the recorder.
709 /// It returns a list containing all the supported video encoders
712 /// <seealso cref="StreamRecorderVideoCodec"/>
713 public IEnumerable<StreamRecorderVideoCodec> SupportedVideoEncodings
717 if (_videoCodec.Count == 0)
719 Native.VideoEncoderCallback callback = (StreamRecorderVideoCodec codec, IntPtr userData) =>
721 _videoCodec.Add(codec);
724 int ret = Native.VideoEncoders(_handle, callback, IntPtr.Zero);
725 if (ret != (int)StreamRecorderError.None)
727 StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported video encoders");
735 /// Retrieves all the video resolutions supported by the recorder.
738 /// It returns videoresolution list containing the width and height of
739 /// different resolutions supported by recorder.
741 /// <seealso cref="StreamRecorderVideoResolution"/>
742 public IEnumerable<StreamRecorderVideoResolution> SupportedVideoResolutions
746 if (_resolutions.Count == 0)
748 Native.VideoResolutionCallback callback = (int width, int height, IntPtr userData) =>
750 StreamRecorderVideoResolution temp = new StreamRecorderVideoResolution(width, height);
751 _resolutions.Add(temp);
754 int ret = Native.VideoResolution(_handle, callback, IntPtr.Zero);
755 if (ret != (int)StreamRecorderError.None)
757 StreamRecorderErrorFactory.ThrowException(ret, "Failed to get the supported video resolutions");
765 /// Prepare the stream recorder.
768 /// Before calling the function, it is required to set <see cref="StreamRecorder.EnableSourceBuffer(StreamRecorderSourceType)"/>,
769 /// <see cref="StreamRecorderAudioCodec"/>, <see cref="StreamRecorderVideoCodec"/> and <see cref="StreamRecorderFileFormat"/> properties of recorder.
771 /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
772 /// <seealso cref="Unprepare"/>
773 public void Prepare()
775 int ret = Native.Prepare(_handle);
776 if (ret != (int)StreamRecorderError.None)
778 StreamRecorderErrorFactory.ThrowException(ret, "Failed to prepare stream recorder");
783 /// Resets the stream recorder.
786 /// The recorder state must be <see cref="StreamRecorderState.Prepared"/> state by <see cref="Prepare"/>, <see cref="Cancel"/> and <see cref="Commit"/>.
787 /// The StreamRecorder state will be <see cref="StreamRecorderState.Created"/>.
789 /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
790 /// <seealso cref="Prepare"/>
791 public void Unprepare()
793 int ret = Native.Unprepare(_handle);
794 if (ret != (int)StreamRecorderError.None)
796 StreamRecorderErrorFactory.ThrowException(ret, "Failed to reset the stream recorder");
801 /// Starts the recording.
804 /// If file path has been set to an existing file, this file is removed automatically and updated by new one.
805 /// The filename should be set before this function is invoked.
806 /// The recorder state must be <see cref="StreamRecorderState.Prepared"/> state by <see cref="Prepare"/> or
807 /// <see cref="StreamRecorderState.Paused"/> state by <see cref="Pause"/>.
808 /// The filename shuild be set by <see cref="FilePath"/>
810 /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
811 /// <exception cref="UnauthorizedAccessException">The access ot the resources can not be granted.</exception>
812 /// <seealso cref="Pause"/>
813 /// <seealso cref="Commit"/>
814 /// <seealso cref="Cancel"/>
815 /// <seealso cref="FilePath"/>
816 /// <seealso cref="FileFormat"/>
819 int ret = Native.Start(_handle);
820 if (ret != (int)StreamRecorderError.None)
822 StreamRecorderErrorFactory.ThrowException(ret, "Failed to start the stream recorder");
827 /// Pause the recording.
830 /// Recording can be resumed with <see cref="Start"/>.
832 /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
833 /// <seealso cref="Start"/>
834 /// <seealso cref="Commit"/>
835 /// <seealso cref="Cancel"/>
838 int ret = Native.Pause(_handle);
839 if (ret != (int)StreamRecorderError.None)
841 StreamRecorderErrorFactory.ThrowException(ret, "Failed to pause the stream recorder");
846 /// Stops recording and saves the result.
849 /// The recorder state must be <see cref="StreamRecorderState.Recording"/> state by <see cref="Start"/> or
850 /// <see cref="StreamRecorderState.Paused"/> state by <see cref="Pause"/>
851 /// When you want to record audio or video file, you need to add privilege according to rules below additionally.
853 /// http://tizen.org/privilege/mediastorage is needed if input or output path are relevant to media storage.
854 /// http://tizen.org/privilege/externalstorage is needed if input or output path are relevant to external storage.
857 /// <exception cref="InvalidOperationException">The streamrecorder is not in the valid state.</exception>
858 /// <exception cref="UnauthorizedAccessException">The access ot the resources can not be granted.</exception>
859 /// <seealso cref="Start"/>
860 /// <seealso cref="Pause"/>
863 int ret = Native.Commit(_handle);
864 if (ret != (int)StreamRecorderError.None)
866 StreamRecorderErrorFactory.ThrowException(ret, "Failed to save the recorded content");
871 /// Cancels the recording.
872 /// The recording data is discarded and not written in the recording file.
874 /// <seealso cref="Start"/>
875 /// <seealso cref="Pause"/>
878 int ret = Native.Cancel(_handle);
879 if (ret != (int)StreamRecorderError.None)
881 StreamRecorderErrorFactory.ThrowException(ret, "Failed to cancel the recording");
886 /// Push stream buffer as recording raw data.
888 public void PushBuffer(MediaPacket packet)
890 IntPtr _packet_h = packet.GetHandle();
892 Log.Info("Tizen.Multimedia.StreamRecorder", "PUSH stream buffer");
893 int ret = Native.PushStreamBuffer(_handle, _packet_h);
894 if (ret != (int)StreamRecorderError.None)
896 StreamRecorderErrorFactory.ThrowException(ret, "Failed to push buffer");
898 Log.Info("Tizen.Multimedia.StreamRecorder", "PUSH stream buffer END");
902 /// Set the source type of pushed data.
904 public void EnableSourceBuffer(StreamRecorderSourceType type)
906 int ret = Native.EnableSourceBuffer(_handle, (int)type);
907 if (ret != (int)StreamRecorderError.None)
909 StreamRecorderErrorFactory.ThrowException(ret, "Failed to set EnableSourceBuffer");
914 /// Release any unmanaged resources used by this object.
916 public void Dispose()
919 GC.SuppressFinalize(this);
922 protected virtual void Dispose(bool disposing)
928 // to be used if there are any other disposable objects
930 if (_handle != IntPtr.Zero)
932 Native.Destroy(_handle);
933 _handle = IntPtr.Zero;
939 private void RegisterStreamRecorderNotifiedEvent()
941 _notifiedCallback = (StreamRecorderState previous, StreamRecorderState current, StreamRecorderNotify notify, IntPtr userData) =>
943 StreamRecorderNotifiedEventArgs eventArgs = new StreamRecorderNotifiedEventArgs(previous, current, notify);
944 _recorderNotified?.Invoke(this, eventArgs);
946 int ret = Native.SetNotifiedCallback(_handle, _notifiedCallback, IntPtr.Zero);
947 if (ret != (int)StreamRecorderError.None)
949 StreamRecorderErrorFactory.ThrowException(ret, "Setting notify callback failed");
953 private void UnregisterStreamRecorderNotifiedEvent()
955 int ret = Native.UnsetNotifiedCallback(_handle);
956 if (ret != (int)StreamRecorderError.None)
958 StreamRecorderErrorFactory.ThrowException(ret, "Unsetting notify callback failed");
962 private void RegisterBufferComsumedEvent()
964 _bufferConsumedCallback = (IntPtr buffer, IntPtr userData) =>
966 StreamRecordingBufferConsumedEventArgs eventArgs = new StreamRecordingBufferConsumedEventArgs(buffer);
967 _bufferConsumed?.Invoke(this, eventArgs);
969 int ret = Native.SetBufferConsumedCallback(_handle, _bufferConsumedCallback, IntPtr.Zero);
970 if (ret != (int)StreamRecorderError.None)
972 StreamRecorderErrorFactory.ThrowException(ret, "Setting buffer consumed callback failed");
976 private void UnregisterBufferComsumedEvent()
978 int ret = Native.UnsetBufferConsumedCallback(_handle);
979 if (ret != (int)StreamRecorderError.None)
981 StreamRecorderErrorFactory.ThrowException(ret, "Unsetting buffer consumed callback failed");
985 private void RegisterRecordingStatusChangedEvent()
987 _recordingStatusCallback = (ulong elapsedTime, ulong fileSize, IntPtr userData) =>
989 RecordingProgressEventArgs eventArgs = new RecordingProgressEventArgs(elapsedTime, fileSize);
990 _recordingStatusChanged?.Invoke(this, eventArgs);
992 int ret = Native.SetStatusChangedCallback(_handle, _recordingStatusCallback, IntPtr.Zero);
993 if (ret != (int)StreamRecorderError.None)
995 StreamRecorderErrorFactory.ThrowException(ret, "Setting status changed callback failed");
999 private void UnregisterRecordingStatusChangedEvent()
1001 int ret = Native.UnsetStatusChangedCallback(_handle);
1002 if (ret != (int)StreamRecorderError.None)
1004 StreamRecorderErrorFactory.ThrowException(ret, "Unsetting status changed callback failed");
1008 private void RegisterRecordingLimitReachedEvent()
1010 _recordingLimitReachedCallback = (StreamRecordingLimitType type, IntPtr userData) =>
1012 StreamRecordingLimitReachedEventArgs eventArgs = new StreamRecordingLimitReachedEventArgs(type);
1013 _recordingLimitReached?.Invoke(this, eventArgs);
1015 int ret = Native.SetLimitReachedCallback(_handle, _recordingLimitReachedCallback, IntPtr.Zero);
1016 if (ret != (int)StreamRecorderError.None)
1018 StreamRecorderErrorFactory.ThrowException(ret, "Setting limit reached callback failed");
1022 private void UnregisterRecordingLimitReachedEvent()
1024 int ret = Native.UnsetLimitReachedCallback(_handle);
1025 if (ret != (int)StreamRecorderError.None)
1027 StreamRecorderErrorFactory.ThrowException(ret, "Unsetting limit reached callback failed");
1031 private void RegisterRecordingErrorOccurredEvent()
1033 _recorderErrorCallback = (StreamRecorderErrorCode error, StreamRecorderState current, IntPtr userData) =>
1035 StreamRecordingErrorOccurredEventArgs eventArgs = new StreamRecordingErrorOccurredEventArgs(error, current);
1036 _recordingErrorOccurred?.Invoke(this, eventArgs);
1038 int ret = Native.SetErrorCallback(_handle, _recorderErrorCallback, IntPtr.Zero);
1039 if (ret != (int)StreamRecorderError.None)
1041 StreamRecorderErrorFactory.ThrowException(ret, "Setting Error callback failed");
1045 private void UnregisterRecordingErrorOccurredEvent()
1047 int ret = Native.UnsetErrorCallback(_handle);
1048 if (ret != (int)StreamRecorderError.None)
1050 StreamRecorderErrorFactory.ThrowException(ret, "Unsetting Error callback failed");