def package_mp4(video_file, audio_files, timestamp): output_file = _create_temp_output_file('%s_packaged' % timestamp) command = _generate_ffmpeg_package_command(video_file, audio_files, output_file) _run_ffmpeg(command) log.debug('Packaged video file saved to %s', output_file) return output_file
def convert_to_srt_file(audio_statuses, timestamp): (_, path) = mkstemp('.srt', 'tfltree_%s_' % timestamp) srt_text = _convert_to_srt_text(audio_statuses) with open(path, 'w') as file: file.write(srt_text) log.debug('Written subtitle file to %s', path) return path
def encode_mp4_with_subtitles(video_file, audio_files, subtitle_file, timestamp): output_file = _create_temp_output_file('%s_subtitled' % timestamp) command = _generate_ffmpeg_burn_subtitles_command(video_file, audio_files, subtitle_file, output_file) _run_ffmpeg(command) log.debug('Subtitled video file saved to %s', output_file) return output_file
def __init__(self): self.camera = picamera.PiCamera() self.camera.resolution = (720, 720) self.camera.awb_mode = 'sunlight' # Warm up status_light.blink() sleep(2) status_light.off() log.debug('Camera warmed up')
def _record_h264(self, seconds, timestamp): (fd, path) = mkstemp('.h264', 'tfltree_%s_' % timestamp) status_light.on() log.debug('Recording for %s seconds', seconds) self.camera.start_recording(path) self.camera.wait_recording(seconds) self.camera.stop_recording() status_light.off() log.debug('Saved video to %s', path) return (fd, path)
def generate_audio_files(line_statuses, timestamp): audio_statuses = generate_phrases_for_status(line_statuses) for index, line_status in enumerate(audio_statuses): (file_handle, file_path) = mkstemp('.wav', 'tfltree_%s_%s_' % (timestamp, index)) log.debug('%s: "%s"', file_path, line_status) generate_speech(file_path, line_status.phrase) duration_ms = speech_duration_ms(file_path) log.debug('%s duration is %sms', file_path, duration_ms) line_status.file_handle = file_handle line_status.file_path = file_path line_status.duration_ms = duration_ms return audio_statuses
def update_status(self, timestamp=strftime('%Y%m%d_%H%M%S')): log.info('Updating status from %s', self.url) response = requests.get(self.url) if response.status_code == 200: self._previous_status = self.status response_text = response.text self.status = _map_status_to_model(json.loads(response_text)) log.info('Loaded status successfully') if self.has_status_changed(): (fd, path) = mkstemp('.json', 'tfltree_%s_' % timestamp) with open(fd, 'w') as f: f.write(response_text) log.debug('Wrote API response to %s', path) else: log.warning('Received status %s from API. Returning previous one', response.status_code) return self.status
def main(): camera = Camera() status_light.blink(0.02, 9.98) leds = lights.start_leds() while True: timestamp = strftime('%Y%m%d_%H%M%S') status = API.update_status(timestamp) lights.show_all_line_statuses(leds, status) if API.has_status_changed(): log.info('Status is different') log.debug(status) lights.lamp_on() audio_statuses = speech.generate_audio_files(status, timestamp) log.debug('Audio files: %r', audio_statuses) total_duration = sum([f.duration_ms for f in audio_statuses]) log.info('Total duration: %sms', total_duration) subtitle_file = subtitle.convert_to_srt_file( audio_statuses, timestamp) lights.play_a_sequence(leds, audio_statuses, 10) video_file = camera.record_for_seconds(total_duration / 1000 + 10, timestamp) audio_filenames = [f.file_path for f in audio_statuses] lights.lamp_off() status_light.blink() log.info('Packaging MP4') packaged_file = video.package_mp4(video_file, audio_filenames, timestamp) status_light.blink(0.9, 0.1) tweet_text = tweets.generate_tweet_text(audio_statuses) tweets.post_video(tweet_text, packaged_file, subtitle_file) status_light.blink(0.02, 9.98) sleep(1200) else: log.debug('Status is the same') sleep(120)
def lamp_off(): log.debug(LAMP_OFF_COMMAND) os.system(LAMP_OFF_COMMAND) log.debug('done')
def lamp_on(): log.debug(LAMP_ON_COMMAND) os.system(LAMP_ON_COMMAND) log.debug('done')
output[line_status_index].affected_lines.add(line_id) output[line_status_index].status_codes.add(status_code) else: output.append(LineStatus( affected_lines=set([line_id]), reason=reason, status_codes=set([status_code]) )) reasons.append(reason) # If there is good service, move it to the end if 'Good Service' in reasons: output.append(output.pop(reasons.index('Good Service'))) # Return a list of deduplicated LineStatus objects return output def _remove_line_name_from_reason(message): index = message.lower().find('line: ') if index >= 0: return message[index + 6:] else: return message if __name__ == '__main__': API = TflApi() status = API.update_status() status2 = API.update_status() log.debug(status) log.debug(API.has_status_changed())
def post_video(tweet_text, video_file, subtitle_file): if enabled: api = twitter.Api(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN_KEY, ACCESS_TOKEN_SECRET) log.debug('Uploading %s to Twitter', video_file) video_id = api.UploadMediaChunked(video_file, media_category='TweetVideo') log.debug('Video ID: %s', video_id) log.debug('Uploading %s to Twitter', subtitle_file) subtitle_id = api.UploadMediaChunked(subtitle_file, media_category='Subtitles') log.debug('Subtitle ID: %s', subtitle_id) api.PostMediaSubtitlesCreate(video_id, subtitle_id, 'en', 'English') log.debug('Successfully associated video with subtitles') attempts = 0 twitter_error = None while attempts < 15: try: status = api.PostUpdate(tweet_text, media=video_id) log.info('Uploaded to Twitter successfully!') log.debug(status) return except TwitterError as e: attempts += 1 log.warn( 'Error from Twitter after %s attempts. Trying a bit later', attempts) sleep(5) twitter_error = e # Exceeded the maximum attempts log.error( 'Twitter upload exceeded the maximum number of attempts. Giving up.' ) log.error(twitter_error) else: log.warning('Twitter upload not enabled. Requires API tokens.')