Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leearmstrong/2b8bbd9e91a8debe8a32 to your computer and use it in GitHub Desktop.
Save leearmstrong/2b8bbd9e91a8debe8a32 to your computer and use it in GitHub Desktop.
Screen recorder for Pythonista
# coding: utf-8
from objc_util import *
from UIKit import *
from Foundation import *
from ReplayKit import *
from console import alert
def main():
rootVC = UIApplication.sharedApplication().keyWindow().rootViewController()
tabVC = rootVC.detailViewController()
methods = [screenRecorderButtonPressed]
ScreenRecorderItemController = create_objc_class('ScreenRecorderItemController', NSObject, methods = methods)
screenRecorderItemController = ScreenRecorderItemController.new()
try:
ScreenRecorderBarButtonItem = ObjCClass('ScreenRecorderBarButtonItem')
except ValueError:
ScreenRecorderBarButtonItem = create_objc_class('ScreenRecorderBarButtonItem', UIBarButtonItem)
screenRecorderItem = ScreenRecorderBarButtonItem.alloc().initWithImage_style_target_action_(ns(ui.Image.named('iob:ios7_videocam_outline_32')), 0, screenRecorderItemController, sel('screenRecorderButtonPressed'))
screenRecorderItemController.screenRecorderItem = screenRecorderItem
leftBarButtonItems = list(tabVC.persistentLeftBarButtonItems())
leftBarButtonItems.append(screenRecorderItem)
tabVC.persistentLeftBarButtonItems = ns(leftBarButtonItems)
tabVC.reloadBarButtonItemsForSelectedTab()
def screenRecorderButtonPressed(_self, _cmd):
from objc_util import ObjCInstance, CGRect
from ReplayKit import RPScreenRecorder
from console import alert
from UIKit import UILabel, UISwitch, UIApplication, UIFont
import ShowTouches
rootVC = UIApplication.sharedApplication().keyWindow().rootViewController()
tabVC = rootVC.detailViewController()
screenRecorderItem = None
for item in tabVC.persistentLeftBarButtonItems():
if item._get_objc_classname().endswith('ScreenRecorderBarButtonItem'):
screenRecorderItem = item
recorder = RPScreenRecorder.sharedRecorder()
if recorder.isRecording():
def recordingStoppedHandler(_cmd, _previewViewController, _error):
if _previewViewController:
screenRecorderItem.image = ns(ui.Image.named('iob:ios7_videocam_outline_32'))
ShowTouches.set_show_touches(False)
previewViewController = ObjCInstance(_previewViewController)
def previewControllerDidFinish_(_self, _cmd, _previewViewController):
previewViewController = ObjCInstance(_previewViewController)
rootVC = UIApplication.sharedApplication().keyWindow().rootViewController()
on_main_thread(rootVC.dismissViewControllerAnimated_completion_)(True, None)
PreviewControllerDelegate = create_objc_class('PreviewControllerDelegate', NSObject, protocols = ['RPPreviewViewControllerDelegate'], methods = [previewControllerDidFinish_])
previewViewController.previewControllerDelegate = PreviewControllerDelegate.new()
previewViewController.modalPresentationStyle = 0
rootVC = UIApplication.sharedApplication().keyWindow().rootViewController()
rootVC.presentViewController_animated_completion_(previewViewController, True, None)
if _error:
error = ObjCInstance(_error)
print error
recordingStoppedHandlerBlock = ObjCBlock(recordingStoppedHandler, None, [c_void_p, c_void_p, c_void_p])
retain_global(recordingStoppedHandlerBlock)
recorder.stopRecordingWithHandler_(recordingStoppedHandlerBlock)
else:
#micEnabled = not bool(alert('Record Screen', 'Start recording Pythonista?', 'Start Recording with Mic', 'Start Recording without Mic') - 1)
screenRecorderSetingsAlert = UIAlertController.alertControllerWithTitle_message_preferredStyle_('Record Screen', '\n\n\n\n\n', 1)
w = screenRecorderSetingsAlert.view().size().width
micLabel = UILabel.alloc().initWithFrame_(CGRect((25, 55), ((150, 31))))
micLabel.text = 'Record Microphone'
micLabel.font = UIFont.boldSystemFontOfSize_(16)
global micSwitch
micSwitch = UISwitch.alloc().initWithFrame_(CGRect((w - 176, 55), (51, 31)))
screenRecorderSetingsAlert.view().addSubview_(micLabel)
screenRecorderSetingsAlert.view().addSubview_(micSwitch)
touchesLabel = UILabel.alloc().initWithFrame_(CGRect((25, 105), ((150, 31))))
touchesLabel.text = 'Show Touches'
touchesLabel.font = UIFont.boldSystemFontOfSize_(16)
global touchesSwitch
touchesSwitch = UISwitch.alloc().initWithFrame_(CGRect((w - 176, 105), (51, 31)))
screenRecorderSetingsAlert.view().addSubview_(touchesLabel)
screenRecorderSetingsAlert.view().addSubview_(touchesSwitch)
screenRecorderSetingsAlert.addAction_(UIAlertAction.actionWithTitle_style_handler_('Close', 1, None))
def alertActionStartRecording(action):
global micSwitch, touchSwitch
micEnabled = micSwitch.on()
showTouches = touchesSwitch.on()
def recordingStartedHandler(_self, _cmd, _error):
if _error:
error = ObjCInstance(_error)
print error.localizedDescription()
elif RPScreenRecorder.sharedRecorder().isRecording():
screenRecorderItem.image = ns(ui.Image.named('iob:ios7_videocam_32'))
ShowTouches.set_show_touches(showTouches)
recordingStartedHandlerBlock = ObjCBlock(recordingStartedHandler, None, [c_void_p, c_void_p, c_void_p])
retain_global(recordingStartedHandlerBlock)
if recorder.isAvailable():
recorder.startRecordingWithMicrophoneEnabled_handler_(micEnabled, recordingStartedHandlerBlock)
alertActionStartRecordingBlock = ObjCBlock(alertActionStartRecording, None, [c_void_p])
retain_global(alertActionStartRecordingBlock)
screenRecorderSetingsAlert.addAction_(UIAlertAction.actionWithTitle_style_handler_('Start Recording', 0, alertActionStartRecordingBlock))
UIApplication.sharedApplication().keyWindow().rootViewController().presentViewController_animated_completion_(screenRecorderSetingsAlert, True, None)
if __name__ == '__main__':
main()
# coding: utf-8
from objc_util import *
from Foundation import NSBundle
NSBundle.bundleWithPath_('/System/Library/Frameworks/ReplayKit.framework').load()
RPScreenRecorder = ObjCClass('RPScreenRecorder')
# coding: utf-8
from objc_util import *
from UIKit import *
from Foundation import *
def __setup():
global __show_touches_setup_complete
try:
return __show_touches_setup_complete
except NameError:
pass
c.method_setImplementation.restype = c_void_p
c.method_setImplementation.argtypes = [c_void_p, c_void_p]
c.method_getImplementation.restype = c_void_p
c.method_getImplementation.argtypes = [c_void_p]
app = UIApplication.sharedApplication()
global __tvs
__tvs = {}
def sendEvent2_(_self, _cmd, _event):
from objc_util import ObjCInstance, CGRect
from UIKit import UIView
try:
self = ObjCInstance(_self)
e = ObjCInstance(_event)
self.sendEvent2_(e)
global __tvs
global __show_touches
if not __show_touches:
if __tvs:
if len(__tvs) > 0:
for k, v in enumerate(__tvs):
v[1].removeFromSuperview()
__tvs.pop(k)
return
for tid in __tvs.keys():
ids = [id(t) for t in e.allTouches().allObjects()]
if not tid in ids:
__tvs[tid][1].removeFromSuperview()
__tvs.pop(tid)
for t in e.allTouches().allObjects():
if t.phase() == 3:
__tvs[id(t)][1].removeFromSuperview()
__tvs.pop(id(t), None)
elif t.phase() == 0:
vc = t.window().rootViewController()
while vc.presentedViewController():
vc = vc.presentedViewController()
v = UIView.new()
v.size = (30, 30)
v.center = t.locationInView_(vc.view())
v.backgroundColor = UIColor.blackColor()
v.alpha = 0.4
v.layer().cornerRadius = 15
v.userInteractionEnabled = False
vc.view().addSubview_(v)
__tvs[id(t)] = [t, v]
elif t.phase() == 1:
__tvs[id(t)][0] = t
vc = t.window().rootViewController()
while vc.presentedViewController():
vc = vc.presentedViewController()
v = __tvs[id(t)][1]
v.center = t.locationInView_(vc.view())
except:
pass
MyApp = create_objc_class('MyApp', NSObject, methods = [sendEvent2_])
newimp = c.method_getImplementation(MyApp.new().sendEvent2_.method)
class_addMethod(UIApplication.ptr, sel('sendEvent2_'), newimp, method_getTypeEncoding(app.sendEvent_.method))
oldimp = c.method_getImplementation(app.sendEvent_.method)
c.method_setImplementation(app.sendEvent_.method, newimp)
c.method_setImplementation(app.sendEvent2_.method, oldimp)
__show_touches_setup_complete = True
def set_show_touches(show_touches):
__setup()
global __show_touches
__show_touches = show_touches
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment