Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Using Everyplay to save screen recording to mobile gallery?

Discussion in 'Unity Everyplay' started by mitchtbh, Jan 1, 2018.

  1. mitchtbh

    mitchtbh

    Joined:
    Dec 8, 2013
    Posts:
    54
    I'm looking to add the ability to record video in a mobile app. Just wanted to be able to have a button that records the screen for up to 20 seconds (potentially with custom options to hide/show certain UI elements), and save to the mobile phones gallery. Not particularly worried about sharing aspects, though there were any options there that would be a bonus.

    I've checked out Unity Everyplay - great video recording and playback, but doesn't seem to have a save video to gallery? If I can that's absolutely perfect. Anyone had experience with this or anything similar to everyplay?
     
  2. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    wilkens likes this.
  3. Pabac

    Pabac

    Joined:
    Jan 2, 2018
    Posts:
    15
    I'm not sure it would be helpful but iOS 11 has video screen record and save directly to Gallery. If you're using Android then...no :p
     
  4. kf1

    kf1

    Joined:
    Feb 20, 2018
    Posts:
    1
    Thanks yasirkula for your post, the plugins are a great help!
    I have the question regarding Everyplay's terms - is it ok to use the plugins without the integration of Everyplay's UI and just use the recording function? If no, which elements are required? And also, what does the "sandbox mode" mean exactly?

    Thanks
     
    Last edited: Feb 20, 2018
  5. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    I don't really know Everyplay's terms either. As Everyplay is part of Unity, I thought it would be fine to use the recorded video freely in a Unity game but maybe I was wrong (I hope not, lol). I also saw sandbox mode in FAQ and I still don't know what it is.
     
  6. wilkens

    wilkens

    Joined:
    Feb 3, 2014
    Posts:
    3
    yasirkula likes this.
  7. jestergames

    jestergames

    Joined:
    Sep 10, 2015
    Posts:
    2
    I read there is no microphone input support. Is there a way to add this?
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    Not that I know of. However, it should be possible to implement it on iOS if the Graphics API is set to OpenGLES. In that scenario, the EveryplayRotFix.mm script is used and in this script, there is an interesting code segment:

    Code (CSharp):
    1. if (assetAudioTrack != nil) {
    2.     AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    3.     [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:assetAudioTrack atTime:insertionPoint error:&error];
    4. }
    While processing the video (flipping it upside down), this code includes the audio of the video in the output. It might be possible to include the microphone input as well by changing the code like this (same changes should be applied to flipVideoAsynchronous function, too; as well as updating the @interface and extern "C" parts):

    Code (CSharp):
    1. + (void)flipVideoSynchronous:(NSURL *)videoURL microphonePath:(NSURL *)microphoneInputURL andOutputPath:(NSString *)exportPath {
    2.     // ...
    3.  
    4.     AVURLAsset *microphoneAsset = [AVURLAsset URLAssetWithURL:microphoneInputURL options:@{ AVURLAssetPreferPreciseDurationAndTimingKey:@YES }];
    5.     AVAssetTrack *microphoneAudioTrack = nil;
    6.     if ([[microphoneAsset tracksWithMediaType:AVMediaTypeAudio] count] != 0) {
    7.         microphoneAudioTrack = [microphoneAsset tracksWithMediaType:AVMediaTypeAudio][0];
    8.     }
    9.  
    10.     // ...
    11.     // Step 1
    12.     // Create a composition with the given asset and insert audio and video tracks into it from the asset
    13.     AVMutableComposition *mutableComposition = [AVMutableComposition composition];
    14.     // ...
    15.  
    16.     if (microphoneAudioTrack != nil) {
    17.         AVMutableCompositionTrack *compositionAudioTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    18.         [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [microphoneAsset duration]) ofTrack:microphoneAudioTrack atTime:insertionPoint error:&error];
    19.     }
    20.  
    21.     // Step 2
    22.     // ...
    23. }
    You should find where the microphone input is located (probably somewhere near the recorded video) and pass its path to the EveryplayRotFix.mm in the microphonePath parameter.

    That is a tedious work but that's the only solution I can think of.
     
  9. FranzBertazzo

    FranzBertazzo

    Joined:
    Mar 18, 2015
    Posts:
    3
    Thanks yasirkula, the plugins are amazing!
    I´m just having an issue with Everyplay video to local storage on iOS, the videos apear to be corrupted. I´m using Metal and EveryplayLocalSaveAsync(). Do you know what might be the cause? It works perfect on Android.
    Code (CSharp):
    1. public void OnPressStopButton()
    2.     {
    3.         Everyplay.StopRecording ();
    4.         ActivateVideoUI (false);
    5.         StartCoroutine( EveryplayLocalSaveAsync() );
    6.     }
    7.  
    8.     private IEnumerator EveryplayLocalSaveAsync()
    9.     {
    10.    
    11.         // Only async on iOS, results immediately on Android
    12.         yield return EveryplayLocalSave.SaveToAsync( Path.Combine( Application.persistentDataPath, "saved video.mp4" ) );
    13.         Debug.Log ("entrou");
    14.         if (EveryplayLocalSave.SavedPath != null)
    15.         {
    16.             Debug.Log ("Video saved to " + EveryplayLocalSave.SavedPath);
    17.         }
    18.             else
    19.             Debug.LogWarning( "Could not save the video; check logs!" );
    20.     }
     
  10. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    By corrupted, do you mean the video is upside-down or it just won't play at all? Does changing the filename parameter as "saved video {0}.mp4" resolve the issue?

    P.S. Also, can you insert Debug.Log("--METAL--"); to line 109 of EveryplayLocalSave.cs (the line inside the if(SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Metal) condition) to see if the message is logged to Xcode console?
     
  11. FranzBertazzo

    FranzBertazzo

    Joined:
    Mar 18, 2015
    Posts:
    3
    The video won´t play at all and if I copy the appdata and play it from another app it says the video is corrupted. Changing the filename parameter to "saved video {0}.mp4" saves the video with the right name without overwriting but it won´t play just the same. I inserted the Debug.Log("--METAL--"); and it shows on Xcode console.
     
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    My guess is that after you call Everyplay.StopRecoring(), Everyplay closes the video stream and possible injects some metadata to the generated mp4 file. This process is asynchronous and after it is finished, Everyplay.RecordingStopped event is called. But in your code, you are trying to access the video before Everyplay adds these finishing touches. Therefore, the video is corrupt (again, this is my guess).

    To possibly solve this problem, you should register to the Everyplay.RecordingStopped event in your code and start the EveryplayLocalSaveAsync() coroutine after the event is fired (similar to the example code in the GitHub page).

    Please let me know if this solves the problem.
     
  13. FranzBertazzo

    FranzBertazzo

    Joined:
    Mar 18, 2015
    Posts:
    3
    It worked perfectly, thank you Yasirkula!
     
  14. xuzhiyuan4

    xuzhiyuan4

    Joined:
    Mar 18, 2018
    Posts:
    4
    _ZV[$J`IN2TR(BI4W(CR5UK.png
    I saved video locally. There is no video in the mobile IOS album. Why?
     
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    This plugin just saves the recorded video to the specified path in local storage in correct orientation. Then, you will have to use another plugin to save that video to Gallery/Photos. If you use my NativeGallery plugin, you can add the following line inside "EveryplayLocalSave.SavedPath != null" condition to save the video to Gallery/Photos:

    Code (CSharp):
    1. NativeGallery.SaveVideoToGallery( EveryplayLocalSave.SavedPath, "Album name", "Recorded Video.mp4" );
    P.S. I'd recommend you to tell the user only that their video is saved to the specified album. Showing the path of the video to the user may be confusing for them. Also, this path will not point to the correct directory on iOS because iOS keeps a separate copy of its media in an internal directory.
     
    Last edited: Mar 29, 2018
    xuzhiyuan4 likes this.
  16. xuzhiyuan4

    xuzhiyuan4

    Joined:
    Mar 18, 2018
    Posts:
    4
    Video is saved successfully,great.
    Thank you yasirkula!
     
    yasirkula likes this.
  17. leebrond

    leebrond

    Joined:
    May 15, 2017
    Posts:
    3
    Hello @yasirkula !
    Thanks for your information about Everyplay, it helps me a lot.
    I'm planning to save the recorded video on local storage and then upload it to my own Server but, i don't think this is a good way to do it because my game is running for about 15 - 20 minutes per round and i can see that the video file size that i recorded was too large.

    Is there another way to achieve this? Or is there any other way to reduce the video file size before i uploaded it to server?

    Thanks
     
  18. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    437
    I think Everyplay does a very good job compressing their videos. I've used ReplayKit on iOS and the recorded video was much larger than Everyplay's.

    You can, however, try fiddling with Everyplay.SetMotionFactor and Everyplay.SetLowMemoryDevice functions. Also, if you are OK with paid solutions, you can ask the author of NatCorder whether or not their plugin can output very small video files.
     
  19. tejarm

    tejarm

    Joined:
    Apr 13, 2018
    Posts:
    1
    can any one tell me how to record the screen.
    thank you