Deleting file: libre-streamer.py replaced by abyss.py
[libre-streamer.git] / stream_2016 / gstconf.py
CommitLineData
669383aa 1#!/usr/bin/env python3.4
dfee4fc3 2# -*- coding: utf-8 -*-
669383aa 3
332e58df 4# This file is part of ABYSS.
dfee4fc3 5# ABYSS Broadcast Your Streaming Successfully
669383aa 6#
332e58df 7# ABYSS is free software: you can redistribute it and/or modify
669383aa
DT
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
332e58df 12# ABYSS is distributed in the hope that it will be useful,
669383aa
DT
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
332e58df 18# along with ABYSS. If not, see <http://www.gnu.org/licenses/>.
669383aa
DT
19#
20# Copyright (c) 2016 David Testé
21
340ab727 22from os import rename
e84c1bd7 23from os import listdir
969dd837 24from os import path
ba4fea24 25from time import localtime, strftime
969dd837 26import configparser
340ab727 27
669383aa
DT
28import gi
29from gi.repository import Gst
30from gi.repository import GstVideo
31
340ab727 32# Pathname has to be defined
969dd837
DT
33AUDIO_DEFAULT = 'AUDIO_DEFAULT'
34RAWVIDEO_DEFAULT = 'RAWVIDEO_DEFAULT'
35STREAM_DEFAULT = 'STREAM_DEFAULT'
ba4fea24 36BACKUP_SUFFIX = '_BACKUP'
3d4734cb
DT
37FAILED_SUFFIX = '_FAILED_'
38fail_counter = 1
ba4fea24
DT
39AUDIO_BACKUP = AUDIO_DEFAULT + BACKUP_SUFFIX
40RAWVIDEO_BACKUP = RAWVIDEO_DEFAULT + BACKUP_SUFFIX
41STREAM_BACKUP = STREAM_DEFAULT + BACKUP_SUFFIX
42ERROR = '[ERROR] '
43INFO = '[INFO] '
44WARN = '[WARN] '
969dd837 45CONFIG = '.abyss'
340ab727 46
969dd837
DT
47sources = {'RTSP_IP' : None,
48 'AUDIO_INPUT' : None,}
49sinks = {'AUDIO_OUTPUT' : None,
50 'DIR': None,
51 'STREAM_SERVER_IP' : None,
52 'SERVER_PORT' : None,
53 'PASSWORD' : None,
54 'AUDIO_MOUNT' : None,
55 'VIDEO_MOUNT' : None,}
56
57##AUDIO_INPUT = 'alsa_input.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00-CODEC.analog-stereo'
58##AUDIO_OUTPUT = 'alsa_output.pci-0000_00_1b.0.analog-stereo'
59
60config = configparser.RawConfigParser()
61if path.exists(CONFIG):
62 config.read(CONFIG)
63 try:
64 sources = {key : config.get('sources', key) for key in sources}
65 sinks = {key : config.get('sinks', key) for key in sinks}
66 except:
67 print(ERROR, gettime(), 'Failed to parse config file.')
68else:
69 print(ERROR, gettime(), '".abyss" config file doesn\'t exist.')
4f6dadd2 70
340ab727 71
669383aa 72class New_user_pipeline():
340ab727 73
669383aa 74
969dd837
DT
75 def __init__(self, feed='main'):
76 self.rtsp_address = 'rtsp://' + sources['RTSP_IP']
e84c1bd7 77 self.feed = feed
ba4fea24 78 self.user_pipeline = self.create_gstreamer_pipeline()
e84c1bd7 79
669383aa
DT
80 def create_video_sources(self):
81 """Create video inputs from various sources."""
82 self.videosrc = Gst.ElementFactory.make('rtspsrc', 'videosrc')
dfee4fc3 83 self.videosrc.set_property('location', self.rtsp_address)
669383aa 84 self.videosrc.set_property('latency', 0)
ba4fea24 85## self.videosrc.set_property('debug', True)
e84c1bd7
DT
86 if self.feed == 'backup':
87 self.videosrc_backup = Gst.ElementFactory.make('v4l2src',
88 'videosrc_backup')
89 device_location = self.find_webcam_device()
e84c1bd7
DT
90 self.videosrc_backup.set_property('device', device_location)
91
92 def find_webcam_device(self):
93 """Look out for the USB webcam device."""
94 devices = [dev for dev in listdir('/dev/') if 'video' in dev]
95 for item in devices:
96 # In case of computer having a built-in webcam
97 if item != 'video0' and len(devices) > 1:
98 return '/dev/' + item
99 # Without built-in webcam
100 elif len(devices) == 1:
101 return '/dev/video0'
ba4fea24 102 print(ERROR, gettime(), 'No webcam device found.')
4f6dadd2
DT
103
104 def find_mixingdesk_device(self):
105 """Look out for the USB mixing desk device.
106 Product used here: Behringer XENYX Q1002USB.
107 """
108 # shell cmd : 'pactl list | grep alsa_input'
109 # AUDIO_INPUT --> const used currently
110 pass
111
669383aa
DT
112 def create_pipeline_callbacks(self):
113 """Callbacks to connect dynamically created pads."""
e84c1bd7 114 self.videosrc.connect('pad-added', self.on_pad_added_to_rtspsrc)
669383aa
DT
115
116 def on_pad_added_to_rtspsrc(self, rtspsrc, pad):
117 """Connect the dynamic 'src'pad of an RTSP source."""
118 sinkpad = self.queuev_1.get_static_pad('sink')
119 pad.link(sinkpad)
120
e84c1bd7
DT
121 def create_audio_sources(self):
122 """Create audio inputs from various sources."""
123 self.audiosrc = Gst.ElementFactory.make('pulsesrc', 'audiosrc')
969dd837 124 self.audiosrc.set_property('device', sources['AUDIO_INPUT'])
e84c1bd7 125
6db3115f
DT
126 def create_audiolevel_plugin(self):
127 """Create audio level plugin to feed a vu-meter."""
128 self.audiolevel = Gst.ElementFactory.make('level', 'audiolevel')
129 self.audiolevel.set_property('interval', 200000000)
130
669383aa
DT
131 def create_filesink(self):
132 """Create storable output elements."""
133 self.disksink_rawvideo = Gst.ElementFactory.make('filesink')
134 #[TO DO]: File location has to be defined
340ab727 135 self.disksink_rawvideo.set_property('location', RAWVIDEO_DEFAULT)
669383aa 136 self.disksink_audio = Gst.ElementFactory.make('filesink')
340ab727 137 self.disksink_audio.set_property('location', AUDIO_DEFAULT)
669383aa 138 self.disksink_stream = Gst.ElementFactory.make('filesink')
340ab727 139 self.disksink_stream.set_property('location', STREAM_DEFAULT)
3d4734cb
DT
140 if self.feed == 'backup':
141 self.disksink_rawvideo.set_property('location', RAWVIDEO_BACKUP)
142 self.disksink_audio.set_property('location', AUDIO_BACKUP)
143 self.disksink_stream.set_property('location', STREAM_BACKUP)
144
669383aa
DT
145 def create_streamsink(self):
146 """Create streamable output elements."""
147 # To local screen:
148 self.screensink = Gst.ElementFactory.make('xvimagesink', 'screensink')
e84c1bd7 149 self.screensink.set_property('sync', False)
dfee4fc3
DT
150 # To local audio output (headphones):
151 self.audiosink = Gst.ElementFactory.make('pulsesink', 'audiosink')
969dd837 152 self.audiosink.set_property('device', sinks['AUDIO_OUTPUT'])
dfee4fc3 153 self.audiosink.set_property('sync', False)
669383aa
DT
154 # To icecast server:
155 self.icecastsink_audio = Gst.ElementFactory.make('shout2send', 'icecastsink_audio')
ba4fea24 156 self.icecastsink_audio.set_property('sync', False)
969dd837
DT
157 self.icecastsink_audio.set_property('ip', sinks['STREAM_SERVER_IP']) #'live2.fsf.org')
158 self.icecastsink_audio.set_property('port', int(sinks['SERVER_PORT']))
159 self.icecastsink_audio.set_property('mount', sinks['AUDIO_MOUNT'])# 'testaudio.ogg')
160 self.icecastsink_audio.set_property('password', sinks['PASSWORD'])#'thahw3Wiez')
669383aa 161 self.icecastsink_stream = Gst.ElementFactory.make('shout2send', 'icecastsink_stream')
ba4fea24 162 self.icecastsink_stream.set_property('sync', False)
969dd837
DT
163 self.icecastsink_stream.set_property('ip', sinks['STREAM_SERVER_IP'])#'live2.fsf.org')
164 self.icecastsink_stream.set_property('port', int(sinks['SERVER_PORT']))#80)
165 self.icecastsink_stream.set_property('mount', sinks['VIDEO_MOUNT'])#'teststream.webm')
166 self.icecastsink_stream.set_property('password', sinks['PASSWORD'])#'thahw3Wiez')
669383aa
DT
167
168 def create_payloader_elements(self):
169 pass
170
171 def create_depayloader_elements(self):
172 self.rtpjpegdepay = Gst.ElementFactory.make('rtpjpegdepay', 'rtpjpegdepay')
173
174 def create_encoder_elements(self):
175 # Audio encoders:
176 self.vorbisenc = Gst.ElementFactory.make('vorbisenc', 'vorbisenc')
177 # Video encoders:
178 self.vp8enc = Gst.ElementFactory.make('vp8enc', 'vp8enc')
179 self.vp8enc.set_property('min_quantizer', 1)
180 self.vp8enc.set_property('max_quantizer', 13)
181 self.vp8enc.set_property('cpu-used', 5)
182 self.vp8enc.set_property('deadline', 42000)
183 self.vp8enc.set_property('threads', 2)
184 self.vp8enc.set_property('sharpness', 7)
185
186 def create_decoder_elements(self):
187 self.jpegdec = Gst.ElementFactory.make('jpegdec', 'jpegdec')
188 self.jpegdec.set_property('max-errors', -1)
189
190 def create_muxer_elements(self):
191 self.oggmux = Gst.ElementFactory.make('oggmux', 'oggmux')
192 self.mkvmux = Gst.ElementFactory.make('matroskamux', 'mkvmux')
193 self.webmmux = Gst.ElementFactory.make('webmmux', 'webmmux')
194 self.webmmux.set_property('streamable', True)
195
196 def create_demuxer_elements(self):
197 pass
198
199 def create_filtering_elements(self):
200 self.scaling = Gst.ElementFactory.make('videoscale', 'scaling')
201 caps = Gst.caps_from_string('video/x-raw, width=(int)640, height=(int)360')
202 self.capsfilter = Gst.ElementFactory.make('capsfilter', 'capsfilter')
203 self.capsfilter.set_property('caps', caps)
e84c1bd7
DT
204
205 caps_backup = Gst.caps_from_string('video/x-raw, width=(int)640, height=(int)360')
206 self.capsfilter_backup = Gst.ElementFactory.make('capsfilter', 'capsfilter_backup')
207 self.capsfilter_backup.set_property('caps', caps_backup)
669383aa
DT
208
209 def create_tee_elements(self):
210 """Create tee elements to divide feeds."""
211 self.tee_rawvideo = Gst.ElementFactory.make('tee', 'tee_rawvideo')
212 self.tee_videodecoded = Gst.ElementFactory.make('tee', 'tee_videodecoded')
213 self.tee_streamfull = Gst.ElementFactory.make('tee', 'tee_streamfull')
214 self.tee_rawaudio = Gst.ElementFactory.make('tee', 'tee_rawaudio')
215 self.tee_streamaudio = Gst.ElementFactory.make('tee', 'tee_streamaudio')
216
217 def connect_tee(self,
218 tee_element,
219 input_element,
220 output_element_1,
ba4fea24
DT
221 output_element_2,
222 output_element_3=None,):
669383aa
DT
223 """Links input and outputs of a given tee element."""
224 # Find a way to check if the element given are in the pipeline
225 # then pass the result to the 'if' statement.
226 ## argcheck = [True for arg in locals() if arg in 'the_list_of_elements_added']
227 ## print('[DEBUG] ArgList check: ', argcheck)
228 ## if False not in argcheck
229 if True:
230 input_element.link(tee_element)
231 tee_element.link(output_element_1)
232 tee_element.link(output_element_2)
ba4fea24
DT
233 if output_element_3:
234 tee_element.link(output_element_3)
669383aa 235 else:
ba4fea24
DT
236 print(ERROR,
237 gettime(),
238 'Couldn\'t link the tee. Element(s) probably not in the pipeline ')
669383aa
DT
239
240 def create_queues(self):
241 # For video feed:
242 self.queuev_1 = Gst.ElementFactory.make('queue', 'queuev_1')
243 self.queuev_2 = Gst.ElementFactory.make('queue', 'queuev_2')
244 self.queuev_3 = Gst.ElementFactory.make('queue', 'queuev_3')
245 self.queuev_4 = Gst.ElementFactory.make('queue', 'queuev_4')
246 self.queuev_5 = Gst.ElementFactory.make('queue', 'queuev_5')
669383aa
DT
247 # For audio feed:
248 self.queuea_1 = Gst.ElementFactory.make('queue', 'queuea_1')
249 self.queuea_2 = Gst.ElementFactory.make('queue', 'queuea_2')
250 self.queuea_3 = Gst.ElementFactory.make('queue', 'queuea_3')
251 self.queuea_4 = Gst.ElementFactory.make('queue', 'queuea_4')
ba4fea24 252 self.queuea_4.set_property('leaky', 2)
669383aa
DT
253 self.queuea_5 = Gst.ElementFactory.make('queue', 'queuea_5')
254 # For audio+video muxer:
255 self.queuem_1 = Gst.ElementFactory.make('queue', 'queuem_1')
256 self.queuem_2 = Gst.ElementFactory.make('queue', 'queuem_2')
ba4fea24 257 self.queuem_2.set_property('leaky', 2)
669383aa
DT
258
259 def create_pipeline_elements(self):
ba4fea24 260 print(INFO, gettime(), 'Pipeline creation state: creating elements... ', end='')
669383aa
DT
261 # Inputs elements:
262 self.create_video_sources()
263 self.create_audio_sources()
264 # Middle elements:
6db3115f 265 self.create_audiolevel_plugin()
669383aa
DT
266 self.create_payloader_elements()
267 self.create_depayloader_elements()
268 self.create_encoder_elements()
269 self.create_decoder_elements()
270 self.create_muxer_elements()
271 self.create_filtering_elements()
272 self.create_tee_elements()
273 self.create_queues()
274 # Output elements:
275 self.create_filesink()
276 self.create_streamsink()
dfee4fc3
DT
277 if self.feed == 'test':
278 print('TEST OK...', end='')
669383aa 279 print('created')
ba4fea24
DT
280 if self.feed == 'backup':
281 print (INFO,
282 gettime(),
283 'Webcam device location: ',
284 self.videosrc_backup.get_property('device'))
669383aa
DT
285
286
ba4fea24
DT
287 def add_elements_to_pipeline(self):
288 print(INFO, gettime(), 'Pipeline creation state: adding elements... ', end='')
dfee4fc3
DT
289 cond = self.feed != 'test'
290
ba4fea24
DT
291 # Inputs elements:
292 self.streampipe.add(self.audiosrc)
293 # Middle elements:
294 self.streampipe.add(self.audiolevel)
ba4fea24 295 self.streampipe.add(self.queuea_1)
dfee4fc3
DT
296 self.streampipe.add(self.queuev_3)
297 if cond:
298 self.streampipe.add(self.vorbisenc)
299 self.streampipe.add(self.oggmux)
300 self.streampipe.add(self.queuea_2)
301 self.streampipe.add(self.queuea_3)
302 self.streampipe.add(self.vp8enc)
303 self.streampipe.add(self.mkvmux)
304 self.streampipe.add(self.webmmux)
305 self.streampipe.add(self.tee_rawaudio)
306 self.streampipe.add(self.tee_rawvideo)
307 self.streampipe.add(self.tee_streamaudio)
308 self.streampipe.add(self.tee_streamfull)
309 self.streampipe.add(self.queuev_2)
310 self.streampipe.add(self.queuev_4)
311 self.streampipe.add(self.queuev_5)
312 self.streampipe.add(self.queuea_4)
313 self.streampipe.add(self.queuea_5)
314 self.streampipe.add(self.queuem_1)
315 self.streampipe.add(self.queuem_2)
ba4fea24
DT
316 # Outputs elements:
317 self.streampipe.add(self.screensink)
dfee4fc3
DT
318 if cond:
319 self.streampipe.add(self.disksink_rawvideo)
320 self.streampipe.add(self.disksink_audio)
321 self.streampipe.add(self.disksink_stream)
322 self.streampipe.add(self.icecastsink_audio)
323 self.streampipe.add(self.icecastsink_stream)
324 else:
325 self.streampipe.add(self.audiosink)
326
327 if self.feed == 'main' or self.feed == 'test':
e84c1bd7
DT
328 # Inputs elements:
329 self.streampipe.add(self.videosrc)
e84c1bd7 330 # Middle elements:
e84c1bd7
DT
331 self.streampipe.add(self.rtpjpegdepay)
332 self.streampipe.add(self.jpegdec)
e84c1bd7
DT
333 self.streampipe.add(self.scaling)
334 self.streampipe.add(self.capsfilter)
e84c1bd7 335 self.streampipe.add(self.tee_videodecoded)
e84c1bd7 336 self.streampipe.add(self.queuev_1)
dfee4fc3
DT
337 if self.feed == 'test':
338 print ('TEST OK...', end='')
ba4fea24
DT
339 elif self.feed == 'backup':
340 # Inputs elements:
e84c1bd7 341 self.streampipe.add(self.videosrc_backup)
ba4fea24 342 # Middle elements:
e84c1bd7 343 self.streampipe.add(self.capsfilter_backup)
e84c1bd7 344 print ('BACKUP OK...', end='')
669383aa
DT
345 print('added')
346
ba4fea24 347 def link_pipeline_elements(self):
669383aa 348 """Link all elements with static pads."""
ba4fea24 349 print(INFO, gettime(), 'Pipeline creation state: linking elements... ', end='')
dfee4fc3
DT
350 cond = self.feed != 'test'
351
ba4fea24
DT
352 # Audio feed:
353 self.audiosrc.link(self.audiolevel)
354 self.audiolevel.link(self.queuea_1)
dfee4fc3
DT
355 if cond:
356 self.queuea_1.link(self.vorbisenc)
357 self.connect_tee(self.tee_rawaudio,
358 self.vorbisenc,
359 self.queuea_2,
360 self.queuea_5,)
361 self.queuea_2.link(self.oggmux)
362 self.connect_tee(self.tee_streamaudio,
363 self.oggmux,
364 self.queuea_3,
365 self.queuea_4,)
366 self.queuea_3.link(self.disksink_audio)
367 self.queuea_4.link(self.icecastsink_audio)
368 self.queuea_5.link(self.webmmux)
369 else:
370 self.queuea_1.link(self.audiosink)
371
ba4fea24 372 # Video feed:
dfee4fc3
DT
373 if cond:
374 self.queuev_2.link(self.mkvmux)
375 self.mkvmux.link(self.queuev_4)
376 self.queuev_4.link(self.disksink_rawvideo)
377 else:
378 self.queuev_1.link(self.rtpjpegdepay)
379 self.rtpjpegdepay.link(self.jpegdec)
380 self.jpegdec.link(self.queuev_3)
ba4fea24 381 self.queuev_3.link(self.screensink)
dfee4fc3 382
ba4fea24 383 # Stream (audio+video) feed:
dfee4fc3
DT
384 if cond:
385 self.vp8enc.link(self.queuev_5)
386 self.queuev_5.link(self.webmmux)
387 self.connect_tee(self.tee_streamfull,
388 self.webmmux,
389 self.queuem_1,
390 self.queuem_2,)
391 self.queuem_1.link(self.disksink_stream)
392 self.queuem_2.link(self.icecastsink_stream)
393 if self.feed == 'main':
394 # linking here RTSP feed
395 self.queuev_1.link(self.rtpjpegdepay)
396 self.connect_tee(self.tee_rawvideo,
397 self.rtpjpegdepay,
398 self.queuev_2,
399 self.jpegdec,)
400 self.connect_tee(self.tee_videodecoded,
401 self.jpegdec,
402 self.queuev_3,
403 self.scaling,)
404 # Stream (video) feed:
405 self.scaling.link(self.capsfilter)
406 self.capsfilter.link(self.vp8enc)
407 elif self.feed == 'backup':
408 # linking here backup feed (WEBCAM)
409 self.videosrc_backup.link(self.capsfilter_backup)
410 self.connect_tee(self.tee_rawvideo,
411 self.capsfilter_backup,
412 self.queuev_2,
413 self.queuev_3,
414 output_element_3=self.vp8enc)
ba4fea24 415## self.capsfilter_backup.link(self.queuev_3)
dfee4fc3
DT
416 print('BACKUP OK...', end='')
417 if not cond:
418 print('TEST OK...', end='')
669383aa
DT
419 print('linked')
420
ba4fea24 421 def create_gstreamer_pipeline(self):
669383aa
DT
422 # New empty pipeline:
423 self.streampipe = Gst.Pipeline()
669383aa 424 self.create_pipeline_elements()
e84c1bd7 425 # Setting-up:
ba4fea24
DT
426 self.add_elements_to_pipeline()
427 self.link_pipeline_elements()
dfee4fc3 428 if self.feed == 'main' or self.feed == 'test':
e84c1bd7 429 self.create_pipeline_callbacks()
669383aa
DT
430
431 global bus
432 bus = self.streampipe.get_bus()
433 bus.add_signal_watch()
434 bus.enable_sync_message_emission()
435 # Used to get messages that GStreamer emits.
436 bus.connect("message", self.on_message)
437
ba4fea24 438 print(INFO, gettime(), 'Pipeline creation state: successfully done.')
669383aa 439 return self.streampipe
6db3115f 440
669383aa
DT
441 def on_message(self, bus, message):
442 t = message.type
443 if t == Gst.MessageType.EOS:
6db3115f 444 self.streampipe.set_state(Gst.State.NULL)
669383aa
DT
445 elif t == Gst.MessageType.ERROR:
446 err, debug = message.parse_error()
ba4fea24 447 print (ERROR, '%s' % err, debug)
e84c1bd7 448
669383aa
DT
449 def stream_play(self):
450 self.streampipe.set_state(Gst.State.PLAYING)
ba4fea24
DT
451 if self.feed == 'backup':
452 print(WARN, gettime(), 'Backup pipeline started.')
453 print(INFO, gettime(), 'PLAYING State resquested')
669383aa
DT
454
455 def stream_stop(self):
456 self.streampipe.set_state(Gst.State.NULL)
ba4fea24
DT
457 print(INFO, gettime(), 'STOPPED State resquested')
458
3d4734cb 459 def set_filenames(self, string, streamfailed=False):
340ab727 460 """Sets filename and location for each sink."""
3d4734cb 461 global fail_counter
340ab727 462 filename = string
969dd837
DT
463 audio = sources['DIR'] + filename + '_AUDIO'
464 rawvideo = sources['DIR'] + filename + '_RAWVIDEO'
465 stream = sources['DIR'] + filename + '_STREAM'
3d4734cb 466 print('FEED STATE: ', self.feed)
ba4fea24 467 if self.feed == 'main':
3d4734cb
DT
468 if streamfailed and filename:
469 audio = audio + FAILED_SUFFIX + str(fail_counter)
470 rawvideo = rawvideo + FAILED_SUFFIX + str(fail_counter)
471 stream = stream + FAILED_SUFFIX + str(fail_counter)
472 rename(AUDIO_DEFAULT, audio)
473 rename(RAWVIDEO_DEFAULT, rawvideo)
474 rename(STREAM_DEFAULT, stream)
475 fail_counter += 1
476 elif streamfailed:
477 audio = AUDIO_DEFAULT + FAILED_SUFFIX + str(fail_counter)
478 rawvideo = RAWVIDEO_DEFAULT + FAILED_SUFFIX + str(fail_counter)
479 stream = STREAM_DEFAULT + FAILED_SUFFIX + str(fail_counter)
480 rename(AUDIO_DEFAULT, audio)
481 rename(RAWVIDEO_DEFAULT, rawvideo)
482 rename(STREAM_DEFAULT, stream)
483 fail_counter += 1
484 else:
485 rename(AUDIO_DEFAULT, audio)
486 rename(RAWVIDEO_DEFAULT, rawvideo)
487 rename(STREAM_DEFAULT, stream)
ba4fea24 488 elif self.feed == 'backup':
3d4734cb 489 print('INSIDE BACKUP RENAMING')
ba4fea24
DT
490 rename(AUDIO_BACKUP, audio)
491 rename(RAWVIDEO_BACKUP, rawvideo)
492 rename(STREAM_BACKUP, stream)
669383aa 493
3d4734cb
DT
494 def rename_files():
495 pass
496
669383aa
DT
497def get_gstreamer_bus():
498 return bus
ba4fea24
DT
499
500def gettime():
501 return strftime('%y-%m-%d_%H:%M:%S ', localtime())