Esempio n. 1
0
        /// <summary>
        /// Private properties.
        /// </summary>
        // The garbage collection thread.
        //private Thread garbageCollectionThread;
        //private static bool garbageThreadRunning = false;

        #endregion

        #region Video Capture

        /// <summary>
        /// Initialize the attributes of the capture session and start capture.
        /// </summary>
        public override bool StartCapture()
        {
            if (!PrepareCapture())
            {
                return(false);
            }

            if (offlineRender)
            {
                Time.captureFramerate = frameRate;
            }

            // init ffmpeg encoding settings
            FFmpegEncoderSettings();

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
            if (gpuEncoding)
            {
                if (FreeTrial.Check())
                {
                    Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in free trial version, fall back to software encoding.");
                    gpuEncoding = false;
                }

                if (SystemInfo.graphicsDeviceVendor == "NVIDIA")
                {
                    // init nvidia encoding settings
                    NvidiaEncoderSettings();
                    nvidiaEncoding = true;
                    if (legacyGpuEncoding)
                    {
                        GPUEncoderSettings();
                        nvidiaEncoding = false;
                    }
                }
                else
                {
                    // init GPU encoding settings
                    GPUEncoderSettings();
                    nvidiaEncoding = false;
                }

                if (gpuEncoding && !nvidiaEncoding)
                {
                    if (!gpuEncoder.instantiated || !gpuEncoder.IsSupported())
                    {
                        Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in current device or settings, fall back to software encoding.");
                        gpuEncoding = false;
                    }
                }
            }
#else
            if (gpuEncoding)
            {
                Debug.LogFormat(LOG_FORMAT, "GPU encoding is only available on windows system, fall back to software encoding.");
                gpuEncoding = false;
            }
#endif

            // Init audio recorder
            if ((!gpuEncoding && captureAudio) || (nvidiaEncoding && captureAudio))
            {
                if (captureMicrophone)
                {
                    if (MicrophoneRecorder.singleton == null)
                    {
                        gameObject.AddComponent <MicrophoneRecorder>();
                    }
                    MicrophoneRecorder.singleton.saveFolderFullPath = saveFolderFullPath;
                    MicrophoneRecorder.singleton.captureType        = captureType;
                    MicrophoneRecorder.singleton.deviceIndex        = deviceIndex;
                    microphoneRecorder = MicrophoneRecorder.singleton;
                }

                if (AudioRecorder.singleton == null)
                {
                    if (GetComponent <DontDestroy>() != null)
                    {
                        // Reset AudioListener
                        AudioListener listener = FindObjectOfType <AudioListener>();
                        if (listener)
                        {
                            Destroy(listener);
                            Debug.LogFormat(LOG_FORMAT, "AudioListener found, reset in game scene.");
                        }
                        gameObject.AddComponent <AudioListener>();
                        gameObject.AddComponent <AudioRecorder>();
                    }
                    else
                    {
                        // Keep AudioListener
                        AudioListener listener = FindObjectOfType <AudioListener>();
                        if (!listener)
                        {
                            listener = gameObject.AddComponent <AudioListener>();
                            Debug.LogFormat(LOG_FORMAT, "AudioListener not found, add a new AudioListener.");
                        }
                        listener.gameObject.AddComponent <AudioRecorder>();
                    }
                }
                AudioRecorder.singleton.saveFolderFullPath = saveFolderFullPath;
                AudioRecorder.singleton.captureType        = captureType;
                audioRecorder = AudioRecorder.singleton;
            }

            // Init ffmpeg muxer
            if ((!gpuEncoding && captureAudio) || (nvidiaEncoding && captureAudio))
            {
                if (FFmpegMuxer.singleton == null)
                {
                    gameObject.AddComponent <FFmpegMuxer>();
                }
                FFmpegMuxer.singleton.ffmpegFullPath     = ffmpegFullPath;
                FFmpegMuxer.singleton.customFileName     = customFileName;
                FFmpegMuxer.singleton.saveFolderFullPath = saveFolderFullPath;
                FFmpegMuxer.singleton.AttachVideoCapture(this);
                FFmpegMuxer.singleton.verticalFlip = verticalFlip;
                if (nvidiaEncoding)
                {
                    if (captureSource != CaptureSource.SCREEN)
                    {
                        FFmpegMuxer.singleton.verticalFlip = !verticalFlip;
                    }
                }
                FFmpegMuxer.singleton.horizontalFlip = horizontalFlip;
            }

            // Init ffmpeg transcoder
            if (gpuEncoding && nvidiaEncoding && !captureAudio)
            {
                if (FFmpegTranscoder.singleton == null)
                {
                    gameObject.AddComponent <FFmpegTranscoder>();
                }
                FFmpegTranscoder.singleton.ffmpegFullPath     = ffmpegFullPath;
                FFmpegTranscoder.singleton.customFileName     = customFileName;
                FFmpegTranscoder.singleton.saveFolderFullPath = saveFolderFullPath;
                FFmpegTranscoder.singleton.AttachVideoCapture(this);
                FFmpegTranscoder.singleton.verticalFlip = verticalFlip;
                if (captureSource != CaptureSource.SCREEN)
                {
                    FFmpegTranscoder.singleton.verticalFlip = !verticalFlip;
                }
                FFmpegTranscoder.singleton.horizontalFlip = horizontalFlip;
            }

            // Init ffmpeg streamer
            if (!gpuEncoding && captureType == CaptureType.LIVE)
            {
                if (FFmpegStreamer.singleton == null)
                {
                    gameObject.AddComponent <FFmpegStreamer>();
                }
                FFmpegStreamer.singleton.ffmpegFullPath = ffmpegFullPath;
                FFmpegStreamer.singleton.captureAudio   = captureAudio;
                FFmpegStreamer.singleton.liveStreamUrl  = liveStreamUrl;
                FFmpegStreamer.singleton.bitrate        = bitrate;
            }

            if (gpuEncoding)
            {
                if (nvidiaEncoding)
                {
                    if (!nvidiaEncoder.StartCapture())
                    {
                        OnCaptureError(new CaptureErrorEventArgs(CaptureErrorCode.VIDEO_CAPTURE_START_FAILED));
                        return(false);
                    }

                    if (captureAudio)
                    {
                        if (!audioRecorder.RecordStarted())
                        {
                            audioRecorder.StartRecord();
                        }

                        if (captureMicrophone)
                        {
                            if (!microphoneRecorder.RecordStarted())
                            {
                                microphoneRecorder.StartRecord();
                            }
                        }
                    }
                }
                else
                {
                    if (!gpuEncoder.StartCapture())
                    {
                        OnCaptureError(new CaptureErrorEventArgs(CaptureErrorCode.VIDEO_CAPTURE_START_FAILED));
                        return(false);
                    }
                }
            }
            else
            {
                if (!ffmpegEncoder.StartCapture())
                {
                    OnCaptureError(new CaptureErrorEventArgs(CaptureErrorCode.VIDEO_CAPTURE_START_FAILED));
                    return(false);
                }

                if (captureAudio)
                {
                    if (!audioRecorder.RecordStarted())
                    {
                        audioRecorder.StartRecord();
                    }
                    if (captureMicrophone)
                    {
                        if (!microphoneRecorder.RecordStarted())
                        {
                            microphoneRecorder.StartRecord();
                        }
                    }
                }

                if (captureType == CaptureType.LIVE)
                {
                    // start ffmpeg live streamer
                    if (!FFmpegStreamer.singleton.streamStarted)
                    {
                        FFmpegStreamer.singleton.StartStream();
                    }
                }
            }

            // Create a blitter object to keep frames presented on the screen
            if (screenBlitter)
            {
                CreateBlitterInstance();
            }

            // Update current status.
            status = CaptureStatus.STARTED;

            // Start garbage collect thread.
            //if (!garbageThreadRunning)
            //{
            //  garbageThreadRunning = true;

            //  if (garbageCollectionThread != null &&
            //    garbageCollectionThread.IsAlive)
            //  {
            //    garbageCollectionThread.Abort();
            //    garbageCollectionThread = null;
            //  }

            //  garbageCollectionThread = new Thread(GarbageCollectionProcess);
            //  garbageCollectionThread.Priority = System.Threading.ThreadPriority.Lowest;
            //  garbageCollectionThread.IsBackground = true;
            //  garbageCollectionThread.Start();
            //}

            Debug.LogFormat(LOG_FORMAT, "Video capture session started.");
            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Initialize the attributes of the capture session and start capture.
        /// </summary>
        public bool StartCapture()
        {
            if (_captureStarted)
            {
                Debug.LogWarningFormat(LOG_FORMAT, "Previous screenshot session not finish yet!");
                OnError(this, CaptureErrorCode.SCREENSHOT_ALREADY_IN_PROGRESS);
                return(false);
            }

            if (string.IsNullOrEmpty(saveFolder))
            {
                saveFolder = Config.saveFolder;
            }
            else
            {
                Config.saveFolder = saveFolder;
            }

            if (captureMode == CaptureMode._360)
            {
                if (projectionType == ProjectionType.NONE)
                {
                    Debug.LogFormat(LOG_FORMAT,
                                    "Projection type should be set for 360 capture, set type to equirect for generating texture properly");
                    projectionType = ProjectionType.EQUIRECT;
                }
                if (projectionType == ProjectionType.CUBEMAP)
                {
                    if (stereoMode != StereoMode.NONE)
                    {
                        Debug.LogFormat(LOG_FORMAT,
                                        "Stereo settings not support for cubemap capture, reset to mono video capture.");
                        stereoMode = StereoMode.NONE;
                    }
                }
                CubemapSizeSettings();
            }
            else if (captureMode == CaptureMode.REGULAR)
            {
                // Non 360 capture doesn't have projection type
                projectionType = ProjectionType.NONE;
            }

            AntiAliasingSettings();

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
            if (Config.isFreeTrial())
            {
                Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in free trial version, fall back to software encoding.");
                hardwareEncoding = false;
            }
            else if (!softwareEncodingOnly &&
                     gpuEncoder.instantiated &&
                     gpuEncoder.IsSupported())
            {
                hardwareEncoding = true;
            }
            else
            {
                Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in this device, fall back to software encoding.");
            }
#endif

#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
            Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported on macOS system, fall back to software encoding.");
            hardwareEncoding = false;
#endif

            if (hardwareEncoding)
            {
                // init hardware encoding settings
                GPUEncoderSettings();

                if (!gpuEncoder.StartScreenShot())
                {
                    OnError(this, CaptureErrorCode.SCREENSHOT_START_FAILED);
                    return(false);
                }
            }
            else
            {
                // init ffmpeg encoding settings
                FFmpegEncoderSettings();

                if (!ffmpegEncoder.StartScreenShot())
                {
                    OnError(this, CaptureErrorCode.SCREENSHOT_START_FAILED);
                    return(false);
                }
            }

            _captureStarted = true;

            // Start garbage collect thread.
            if (!garbageThreadRunning)
            {
                garbageThreadRunning = true;

                if (garbageCollectionThread != null &&
                    garbageCollectionThread.IsAlive)
                {
                    garbageCollectionThread.Abort();
                    garbageCollectionThread = null;
                }

                garbageCollectionThread              = new Thread(GarbageCollectionProcess);
                garbageCollectionThread.Priority     = System.Threading.ThreadPriority.Lowest;
                garbageCollectionThread.IsBackground = true;
                garbageCollectionThread.Start();
            }

            Debug.LogFormat(LOG_FORMAT, "Screen shot session started.");
            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// Initialize the attributes of the capture session and start capture.
        /// </summary>
        public bool StartCapture()
        {
            if (status != CaptureStatus.READY)
            {
                Debug.LogWarningFormat(LOG_FORMAT, "Previous video capture session not finish yet!");
                OnError(this, CaptureErrorCode.VIDEO_CAPTURE_ALREADY_IN_PROGRESS);
                return(false);
            }

            if (!File.Exists(Config.ffmpegPath))
            {
                Debug.LogErrorFormat(LOG_FORMAT,
                                     "FFmpeg not found, please follow document and add ffmpeg executable before start capture!");
                OnError(this, CaptureErrorCode.FFMPEG_NOT_FOUND);
                return(false);
            }

            if (inputTexture == null)
            {
                Debug.LogErrorFormat(LOG_FORMAT, "Input render texture not found, please attach input render texture!");
                OnError(this, CaptureErrorCode.INPUT_TEXTURE_NOT_FOUND);
                return(false);
            }

            if (string.IsNullOrEmpty(saveFolder))
            {
                saveFolder = Config.saveFolder;
            }
            else
            {
                Config.saveFolder = saveFolder;
            }

            if (frameRate < 18)
            {
                frameRate = 18;
                Debug.LogFormat(LOG_FORMAT, "Minimum frame rate is 18, set frame rate to 18.");
            }

            if (frameRate > 120)
            {
                frameRate = 120;
                Debug.LogFormat(LOG_FORMAT, "Maximum frame rate is 120, set frame rate to 120.");
            }

            if (captureAudio && offlineRender)
            {
                Debug.LogFormat(LOG_FORMAT, "Audio capture not supported in offline render mode, disable audio capture!");
                captureAudio = false;
            }

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
            if (Config.isFreeTrial())
            {
                Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in free trial version, fall back to software encoding.");
                hardwareEncoding = false;
            }
            else if (!softwareEncodingOnly &&
                     gpuEncoder.instantiated &&
                     gpuEncoder.IsSupported())
            {
                hardwareEncoding = true;
            }
            else
            {
                Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in this device, fall back to software encoding.");
            }
#endif

#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
            Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported on macOS system, fall back to software encoding.");
            hardwareEncoding = false;
#endif

            // Init ffmpeg audio capture
            if (!hardwareEncoding && captureAudio && !FFmpegMuxer.singleton)
            {
                AudioListener listener = FindObjectOfType <AudioListener>();
                if (!listener)
                {
                    Debug.LogFormat(LOG_FORMAT, "AudioListener not found, disable audio capture!");
                    captureAudio = false;
                }
                else
                {
                    listener.gameObject.AddComponent <FFmpegMuxer>();
                }
            }

            if (hardwareEncoding)
            {
                // init GPU encoding settings
                GPUEncoderSettings();

                if (!gpuEncoder.StartCapture())
                {
                    OnError(this, CaptureErrorCode.VIDEO_CAPTURE_START_FAILED);
                    return(false);
                }
            }
            else
            {
                // init ffmpeg encoding settings
                FFmpegEncoderSettings();

                if (!ffmpegEncoder.StartCapture())
                {
                    OnError(this, CaptureErrorCode.VIDEO_CAPTURE_START_FAILED);
                    return(false);
                }

                if (captureAudio)
                {
                    // start ffmpeg audio encoding
                    if (!FFmpegMuxer.singleton.captureStarted)
                    {
                        FFmpegMuxer.singleton.StartCapture();
                    }
                    FFmpegMuxer.singleton.AttachVideoCapture(this);
                }
            }

            // Update current status.
            status = CaptureStatus.STARTED;

            // Start garbage collect thread.
            if (!garbageThreadRunning)
            {
                garbageThreadRunning = true;

                if (garbageCollectionThread != null &&
                    garbageCollectionThread.IsAlive)
                {
                    garbageCollectionThread.Abort();
                    garbageCollectionThread = null;
                }

                garbageCollectionThread              = new Thread(GarbageCollectionProcess);
                garbageCollectionThread.Priority     = System.Threading.ThreadPriority.Lowest;
                garbageCollectionThread.IsBackground = true;
                garbageCollectionThread.Start();
            }

            if (offlineRender)
            {
                // Backup maximumDeltaTime states.
                originalMaximumDeltaTime = Time.maximumDeltaTime;
                Time.maximumDeltaTime    = Time.fixedDeltaTime;
            }

            Debug.LogFormat(LOG_FORMAT, "Video capture session started.");
            return(true);
        }
Esempio n. 4
0
        /// <summary>
        /// Initialize the attributes of the capture session and start capture.
        /// </summary>
        public bool StartCapture()
        {
            if (_captureStarted)
            {
                Debug.LogWarningFormat(LOG_FORMAT, "Previous screenshot session not finish yet!");
                OnCaptureError(new CaptureErrorEventArgs(CaptureErrorCode.SCREENSHOT_ALREADY_IN_PROGRESS));
                return(false);
            }

            saveFolderFullPath = Utils.CreateFolder(saveFolder);

            if (captureMode == CaptureMode._360)
            {
                if (projectionType == ProjectionType.NONE)
                {
                    Debug.LogFormat(LOG_FORMAT,
                                    "Projection type should be set for 360 capture, set type to equirect for generating texture properly");
                    projectionType = ProjectionType.EQUIRECT;
                }
                if (projectionType == ProjectionType.CUBEMAP)
                {
                    if (stereoMode != StereoMode.NONE)
                    {
                        Debug.LogFormat(LOG_FORMAT,
                                        "Stereo settings not support for cubemap capture, reset to mono video capture.");
                        stereoMode = StereoMode.NONE;
                    }
                }
                CubemapSizeSettings();
            }
            else if (captureMode == CaptureMode.REGULAR)
            {
                // Non 360 capture doesn't have projection type
                projectionType = ProjectionType.NONE;
            }

            AntiAliasingSettings();

            // init ffmpeg encoding settings
            FFmpegEncoderSettings();

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
            if (gpuEncoding)
            {
                if (FreeTrial.Check())
                {
                    Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in free trial version, fall back to software encoding.");
                    gpuEncoding = false;
                }

                // init GPU encoding settings
                GPUEncoderSettings();

                if (!gpuEncoder.instantiated || !gpuEncoder.IsSupported())
                {
                    Debug.LogFormat(LOG_FORMAT, "GPU encoding is not supported in current device or settings, fall back to software encoding.");
                    gpuEncoding = false;
                }
            }
#else
            if (gpuEncoding)
            {
                Debug.LogFormat(LOG_FORMAT, "GPU encoding is only available on windows system, fall back to software encoding.");
                gpuEncoding = false;
            }
#endif

            if (gpuEncoding)
            {
                // init hardware encoding settings
                GPUEncoderSettings();

                if (!gpuEncoder.StartScreenShot())
                {
                    OnCaptureError(new CaptureErrorEventArgs(CaptureErrorCode.SCREENSHOT_START_FAILED));
                    return(false);
                }
            }
            else
            {
                if (!ffmpegEncoder.StartScreenShot())
                {
                    OnCaptureError(new CaptureErrorEventArgs(CaptureErrorCode.SCREENSHOT_START_FAILED));
                    return(false);
                }
            }

            _captureStarted = true;

            // Start garbage collect thread.
            //if (!garbageThreadRunning)
            //{
            //  garbageThreadRunning = true;

            //  if (garbageCollectionThread != null &&
            //    garbageCollectionThread.IsAlive)
            //  {
            //    garbageCollectionThread.Abort();
            //    garbageCollectionThread = null;
            //  }

            //  garbageCollectionThread = new Thread(GarbageCollectionProcess);
            //  garbageCollectionThread.Priority = System.Threading.ThreadPriority.Lowest;
            //  garbageCollectionThread.IsBackground = true;
            //  garbageCollectionThread.Start();
            //}

            Debug.LogFormat(LOG_FORMAT, "Screen shot session started.");
            return(true);
        }