Types of recording

Time recording

Add the following line of code where you want to start a recording:

Megacool.shared()?.startRecording(self.view)

The recording will by default keep a buffer of the last 5 seconds. Old frames get overwritten by new frames. See Max Frames for editing the default setting.

To end a recording, add the following line of code:

Megacool.shared()?.stopRecording()

Highlight recording

The highlight recording feature records the ‘most interesting’ part of your game--whether this is an awesome action sequence, or a hilarious ‘fail’. It does this by keeping track of the gameplay's intensity as determined by metrics specific to your game.

Whenever a critical event (such as scoring a point, landing a cool combo, failing in an epic way, etc.) occurs, call this function to make note of the event (and optionally, its intensity):

Megacool.shared()?.registerScoreChange() // without intensity
Megacool.shared()?.registerScoreChange(42) // with intensity of 42

For easy integration, we suggest ‘piggy-backing’ off your game’s current score system by calling this function whenever the player’s score increases, with the amount that it increases by. We equate ‘intensity’ with a change in point value, but you can also experiment with assigning various intensities to events with subjective ‘cool’ value.

Add the following line of code at the beginning of your game to start capturing your highlight!

Megacool.shared()?.startRecording(self.view) { config in
config.overflowStrategy = .highlight
}

Peak location

Different games have different paces: in one game, an awesome move might be followed immediately by bland downtime, while in another game, there might be some cool graphics or an interesting cutscene immediately afterwards. To let you adjust how much to include after the action dies down, try experimenting with the peakLocation parameter. This parameter is specific to highlight recording and controls where the ‘peak’ (or, maximum change in point value) of your highlight occurs. In the previous example, we would want the first game to have a late peak location so we don't record too much boring downtime, and the first game to have an early peak location so we make sure to record the cool after-graphics. The value of the peak location (between 0 and 1, inclusive), determines at what percentage through the recording the peak will be placed.

For example, in a recording with 10 frames, a peakLocation of 0.2 means that the peak will occur near the beginning around frame 2, and a peakLocation of 0.8 means that the peak will occur near the end around frame 8. The default peakLocation is 0.7. You can set the peak location by calling:

Megacool.shared()?.startRecording(self.view) { config in
config.overflowStrategy = .highlight
config.peakLocation = 0.5
}

Frame-by-frame recording

Capture each frame of the recording, e.g. on each user tap:

Megacool.shared()?.captureFrame(self.view)

By default max 50 frames will be captured. If it exceeds 50 frames, old frames are overwritten until stopRecording gets called to reset it. Add the following line of code to stop a recording:

Megacool.shared()?.stopRecording()

Timelapse

Timelapse is identical to the normal captureFrame, except timelapse has different behavior when overflowing maxFrames. If it's about to overflow, it will delete every other frame captured so far, and half the rate of capturing (thus only storing every second image on the first overflow, every fourth image on the next, and so on).

Megacool.shared()?.captureFrame(self.view) { config in
config?.overflowStrategy = .timelapse
}

If you want to guarantee that a frame is added to the timelapse (like an end screen or final state of the game), pass a forceAdd = true parameter to captureFrame like this:

Megacool.shared()?.captureFrame(self.view, withConfig:nil, forceAdd:true)

Important: Only pass this parameter once! Normally this function returns as soon as it has spawned a thread to do the actual capture, but if you pass forceAdd = true it will run synchronously (e.g. not return until it has actually stored the frame. This is because usually this is called as the last step before a session ends and the GIF is created, thus we need the call to complete before creating the GIF. This enables you to change visible elements on the screen after this call completes and be sure that it's not going to be included in the GIF.

Screenshot sharing

Screenshot sharing is possible by either using the helper function shareScreenshot or by setting max frames to 1 on a recording. The helper function will capture the screenshot and open the share modal, then delete the recording from disk afterwards.

Megacool.shared()?.shareScreenshot(self.view)

If you want to show a preview of the screenshot before sharing, you need to use a regular recording with max frames set to 1.


Rendering preview

This creates a rendered preview of the GIF that can be displayed to the user before sharing.

Call startAnimating / stopAnimating to play/pause the animation of the GIF. But you're free to change the size later. If you want to do something advanced with this preview, please review the UIImageView documentation.

if let preview = Megacool.shared()?.getPreview() {
self.view.addSubview(preview)
preview.startAnimating()
} else {
print("Previewing GIF failed, not showing the preview")
}

Customize position and size of the rendered GIF preview that can be showed before sharing:

let preview = Megacool.shared()?.getPreviewWithConfig {config in
config.previewFrame = CGRect(x: 100, y: 100, width: 200, height: 300)
}

Recording frame rate

Set numbers of frames to record per second. Recommended range: 1 - 10. The default is 10:

Megacool.shared()?.startRecording(self.view) { config in
config.frameRate = 8
}

Note: This only applies to recordings made with startRecording, not captureFrame.

Frame rate examples (with Playback frame rate: 10):

Frame rate: 5
Frame rate: 10
Frame rate: 25

Playback frame rate

Set the number of frames per second when playing the GIF. The default is 12 frames / second. The GIF will be exported with this frame rate and it doesn't affect the recording frame rate. Setting this value higher than the frame rate causes the recording to be sped up, setting it lower means it'll be slowed down.

Megacool.shared()?.startRecording(self.view) { config in
config.playbackFrameRate = 11
}
Playback frame rate: 5
Playback frame rate: 10
Playback frame rate: 25

Max frames

Max number of frames to record, default is 50 frames. Setting this to 1 will create a screenshot instead of a GIF. Change the maximum amount of captured frames by setting:

Megacool.shared()?.startRecording(self.view) { config in
config.maxFrames = 25
}
Max frames: 25
Max frames: 50
Max frames: 100

Delay last frame

Set a delay (in milliseconds) for the last frame of the GIF. The default is 1 second to give a natural break before the GIF loops again.

Megacool.shared()?.startRecording(self.view) { config in
config.lastFrameDelay = 2000
}
No extra delay on the last frame
1000 ms delay (default)
2000 ms delay

Last frame overlay

With last frame overlay you can add a transparent image on top of the last GIF frame.

+ =
Megacool.shared()?.startRecording(self.view) { config in
config.lastFrameOverlay = UIImage(named: "overlay.png")
}

Color table

A GIF consists of 256 colors and there are three different ways we can compute those colors, with slightly varying quality and performance tradeoffs. Default is dynamic.

Dynamic

The frames are analyzed before encoding, yielding a good balance between quality and speed. This is the default.

Analyze first

The frames are analyzed before encoding to generate a representative color table. This requires more CPU to create the GIF, but often yields better results when a GIF contains many shades of the same color. This option is only available on iOS, on Android the dynamic color table will be used instead.

Megacool.shared()?.gifColorTable = MCLGIFColorTable.analyzeFirst

Save recordings

Being able to save and resume recordings is useful for combining multiple game sessions together. These recordings are stored to disk to be retrieved and potentially resumed later. This is a great case for turn-based games like Words with Friends where waiting for the other user to finish the round could take many hours, and still create a GIF of the whole game play.

Start and resume a recording

All completed recordings will by default be deleted whenever a new recording is started with either captureFrame or startRecording. To save a recording you can set Megacool.shared()?.keepCompletedRecordings = true

To save multiple recordings you can set a recordingId in the config object at startRecording(_: withConfig:) or captureFrame(_: withConfig:). The recordingId can be anything you prefer, for instance a name of the current level like "level3".

A recording with a given recordingId can be resumed until stopRecording is called. After calling stopRecording you can either share the recording or start a new one from scratch with the same recordingId.

// Save recording of level 3 to disk
Megacool.shared()?.keepCompletedRecordings = true
Megacool.shared()?.startRecording(self.view) { config in
config.recordingId = "level3"
}

Pause recording

When you want to pause a recording that can be continued later, you call pauseRecording.

Megacool.shared()?.pauseRecording()

Delete recording

deleteRecording will remove any frames of the recording in memory and on disk. Both completed and incomplete recordings will take space on disk, thus particularly if you're using Megacool.shared()?.keepCompletedRecordings = true you might want to provide an interface to your users for removing recordings they don't care about anymore to free up space for new recordings.

Megacool.shared()?.deleteRecording("level3")

Show a GIF from a specific recording

To show a GIF from a specific recording:

if let preview = Megacool.shared()?.getPreviewWithConfig({ $0?.recordingId = "level3"}) {
self.view.addSubview(preview)
preview.startAnimating()
} else {
print("Previewing GIF failed, not showing the preview")
}

Share a GIF from a specific recording

To share a GIF from a specific recording you pass the RecordingId as a parameter to presentShare(config:).

Megacool.shared()?.presentShare { config in
config.recordingId = "level3"
}

Note: presentShare calls pauseRecording automatically, so if you haven't called stopRecording before next time you call startRecording, the recording will continue from where you paused.