-
Notifications
You must be signed in to change notification settings - Fork 7
/
VideoRecorder.py
151 lines (119 loc) · 5.9 KB
/
VideoRecorder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# Copyright (C) 2014 AG Projects. See LICENSE for details.
#
# TODO: Video broken since 10.13
from AVFoundation import (AVCaptureScreenInput,
AVCaptureDeviceInput,
AVCaptureDevice,
AVCaptureMovieFileOutput,
AVCaptureSession,
AVCaptureSessionPresetHigh,
AVMediaTypeAudio,
AVMediaTypeMuxed
)
from Foundation import NSObject, NSURL, NSString
from Quartz import CGMainDisplayID
import datetime
import os
import time
import uuid
import urllib.request, urllib.parse, urllib.error
from application.system import makedirs
from sipsimple.configuration.settings import SIPSimpleSettings
from util import run_in_gui_thread, format_identity_to_string
from sipsimple.util import ISOTimestamp
from HistoryManager import ChatHistory
from BlinkLogger import BlinkLogger
class VideoRecorder(object):
started = False
stopped = False
captureSession = None
movieOutput = None
@run_in_gui_thread
def __init__(self, videoController=None):
self.videoController = videoController
settings = SIPSimpleSettings()
filename = "%s-%s.mp4" % (datetime.datetime.now().strftime("%Y%m%d-%H%M%S"), self.sessionController.remoteAOR)
path = os.path.join(settings.audio.directory.normalized, self.sessionController.account.id)
self.recording_path=os.path.join(path, filename)
@property
def sessionController(self):
return self.videoController.sessionController
def init_session(self):
self.captureSession = AVCaptureSession.alloc().init()
self.captureSession.beginConfiguration()
self.captureSession.setSessionPreset_(AVCaptureSessionPresetHigh)
# add screen input
display = CGMainDisplayID()
captureScreenInput = AVCaptureScreenInput.alloc().initWithDisplayID_(display)
self.captureSession.addInput_(captureScreenInput)
self.movieOutput = AVCaptureMovieFileOutput.alloc().init()
self.captureSession.addOutput_(self.movieOutput)
self.captureSession.commitConfiguration()
def captureOutput_didStartRecordingToOutputFileAtURL_fromConnections_(self, captureOutput, outputFileURL, connections):
BlinkLogger().log_info("Started video recording to %s" % self.recording_path)
def captureOutput_didFinishRecordingToOutputFileAtURL_fromConnections_error_(self, captureOutput, outputFileURL, connections, error):
self.addRecordingToHistory(self.recording_path)
BlinkLogger().log_info("Saved video recording to %s" % self.recording_path)
def captureOutput_willFinishRecordingToOutputFileAtURL_fromConnections_error_(self, captureOutput, outputFileURL, connections, error):
BlinkLogger().log_info("Video recording to %s ended with error: %s" % (self.recording_path, error))
def captureOutput_didPauseRecordingToOutputFileAtURL_fromConnections_(self, captureOutput, outputFileURL, connections):
BlinkLogger().log_info("Paused video recording to %s" % self.recording_path)
def captureOutput_didResumeRecordingToOutputFileAtURL_fromConnections_(self, captureOutput, outputFileURL, connections):
BlinkLogger().log_info("Resumed video recording to %s" % self.recording_path)
def addRecordingToHistory(self, filename):
message = "<h3>Video Call Recorded</h3>"
message += "<p>%s" % filename
message += "<p><video src='%s' width=800 controls='controls'>" % urllib.parse.quote(filename)
media_type = 'video-recording'
local_uri = format_identity_to_string(self.sessionController.account)
remote_uri = format_identity_to_string(self.sessionController.target_uri)
direction = 'incoming'
status = 'delivered'
cpim_from = format_identity_to_string(self.sessionController.target_uri)
cpim_to = format_identity_to_string(self.sessionController.target_uri)
timestamp = str(ISOTimestamp.now())
self.add_to_history(media_type, local_uri, remote_uri, direction, cpim_from, cpim_to, timestamp, message, status)
def add_to_history(self,media_type, local_uri, remote_uri, direction, cpim_from, cpim_to, timestamp, message, status):
ChatHistory().add_message(str(uuid.uuid1()), media_type, local_uri, remote_uri, direction, cpim_from, cpim_to, timestamp, message, "html", "0", status)
self.videoController = None
@run_in_gui_thread
def start(self):
if self.started:
return
self.init_session()
self.started = True
self.captureSession.startRunning()
movieURL = NSURL.fileURLWithPath_(self.recording_path)
self.movieOutput.startRecordingToOutputFileURL_recordingDelegate_(movieURL, self)
@run_in_gui_thread
def stop(self):
if not self.started:
self.videoController = None
return
if self.stopped:
return
self.stopped = True
if self.movieOutput.isRecordingPaused() or self.movieOutput.isRecording():
self.movieOutput.stopRecording()
if self.captureSession.isRunning():
self.captureSession.stopRunning()
self.movieOutput = None
self.captureSession = None
def toggleRecording(self):
if not self.started:
self.start()
else:
if self.movieOutput.isRecordingPaused():
self.resume()
else:
self.pause()
@run_in_gui_thread
def pause(self):
if self.movieOutput.isRecording():
self.movieOutput.pauseRecording()
@run_in_gui_thread
def resume(self):
if self.movieOutput.isRecordingPaused():
self.movieOutput.resumeRecording()
def isRecording(self):
return self.started and self.movieOutput and self.movieOutput.isRecording() and not self.movieOutput.isRecordingPaused()