def parse_from_json_object(cls, json_object): id_ = json_object.get('id') if id_ is None: raise BitmovinApiError('Invalid json object: missing field \'id\'') path = json_object.get('path') if path is None: raise BitmovinApiError( 'Invalid json object: missing field \'path\'') cloud_region = json_object.get('cloudRegion') messages = json_object.get('messages') audio_streams = json_object.get('audioStreams') video_streams = json_object.get('videoStreams') meta_streams = json_object.get('metaStreams') subtitle_streams = json_object.get('subtitleStreams') meta_data = json_object.get('metaData') details = AnalysisDetails(id_=id, path=path, cloud_region=cloud_region, audio_streams=audio_streams, video_streams=video_streams, meta_streams=meta_streams, subtitle_streams=subtitle_streams, messages=messages, meta_data=meta_data) return details
def add_video_adaptation_set(self, object_, manifest_id, period_id): if not isinstance(object_, VideoAdaptationSet): raise InvalidTypeError( 'object_ has to be an instance of {}'.format( VideoAdaptationSet.__name__)) url = self.relative_url if not url.endswith('/'): url += '/' url = urljoin( url, '{}/periods/{}/adaptationsets/video'.format( manifest_id, period_id)) response = self.http_client.post(url, object_) # type: Response if response.status == Status.ERROR.value: raise BitmovinApiError( 'Response was not successful: {}'.format( response.raw_response), response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_resource_from_response( response=response, class_=VideoAdaptationSet) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def wait_until_running(self, encoding_id, check_interval=5, timeout=-1): status_response = None encoding_status = EncodingStatus(None) start_time = time.time() while encoding_status.status != 'RUNNING' and encoding_status.status != 'ERROR': TimeoutUtils.raise_error_if_timeout_reached( start_time_in_seconds=start_time, timeout_in_seconds=timeout) status_response = self.status(encoding_id=encoding_id) encoding_status = status_response.resource # type: EncodingStatus self.logger.info("Encoding status: {}".format( encoding_status.status)) self.logger.info( "Will check again in {} seconds...".format(check_interval)) time.sleep(check_interval) self.logger.info("Encoding Status: {}".format( json.dumps(obj=encoding_status, cls=BitmovinJSONEncoder))) if encoding_status.status == 'RUNNING': return True raise BitmovinApiError( "Encoding with ID '{}' was not successfull! Status: {}".format( encoding_id, encoding_status.status), status_response)
def wait_until_analysis_finished(self, input_id, analysis_id, check_interval=5, timeout=-1): status_response = None analysis_status = AnalysisStatus(None) start_time = time.time() while analysis_status.status != 'FINISHED' and analysis_status.status != 'ERROR': TimeoutUtils.raise_error_if_timeout_reached( start_time_in_seconds=start_time, timeout_in_seconds=timeout) status_response = self.retrieve_analysis_status( input_id=input_id, analysis_id=analysis_id) analysis_status = status_response.resource # type: AnalysisStatus self.logger.info("Analysis status: {}".format( analysis_status.status)) self.logger.info( "Will check again in {} seconds...".format(check_interval)) time.sleep(check_interval) self.logger.info("Analysis Status: {}".format( json.dumps(obj=analysis_status, cls=BitmovinJSONEncoder))) if analysis_status.status == 'FINISHED': return True raise BitmovinApiError( "Analysis with ID '{}' (Input {}) was not successfull! Status: {}". format(analysis_id, input_id, analysis_status.status), status_response)
def add_content_protection_to_drm_fmp4_represenation( self, object_, manifest_id, period_id, adaptationset_id, representation_id): if not isinstance(object_, ContentProtection): raise InvalidTypeError( 'object_ has to be an instance of {}'.format( ContentProtection.__name__)) url = self.relative_url if not url.endswith('/'): url += '/' url = urljoin( url, '{}/periods/{}/adaptationsets/{}/representations/fmp4/drm/{}/contentprotection' .format(manifest_id, period_id, adaptationset_id, representation_id)) response = self.http_client.post(url, object_) # type: Response if response.status == Status.ERROR.value: raise BitmovinApiError( 'Response was not successful: {}'.format( response.raw_response), response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_resource_from_response( response=response, class_=ContentProtection) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def wait_until_finished(self, manifest_id, check_interval=5, timeout=-1): status_response = None manifest_status = ManifestStatus() start_time = time.time() while manifest_status.status != 'FINISHED' and manifest_status.status != 'ERROR': TimeoutUtils.raise_error_if_timeout_reached( start_time_in_seconds=start_time, timeout_in_seconds=timeout) status_response = self.status(manifest_id=manifest_id) manifest_status = status_response.resource # type: ManifestStatus self.logger.info("Manifest status: {}".format( manifest_status.status)) self.logger.info( "Will check again in {} seconds...".format(check_interval)) time.sleep(check_interval) self.logger.info("Manifest Status: {}".format( json.dumps(obj=manifest_status, cls=BitmovinJSONEncoder))) if manifest_status.status == 'FINISHED': return True raise BitmovinApiError( "Manifest with ID '{}' was not successfull! Status: {}".format( manifest_id, manifest_status.status), status_response)
def _parse_error_response(self, response: dict): self.logger.info('Parsing error response ...') if response.get('status') is None: raise BitmovinApiError( 'Retrieved invalid response from API: {}'.format( json.dumps(response))) parsed_response = Response.parse_from_json_object(response) return parsed_response
def parse_from_json_object(cls, json_object): input_id = json_object.get('inputId') if input_id is None: raise BitmovinApiError( 'Invalid json object: missing field \'inputId\'') input_path = json_object.get('inputPath') if input_path is None: raise BitmovinApiError( 'Invalid json object: missing field \'inputPath\'') details_json = json_object.get('details') if details_json is None: raise BitmovinApiError( 'Invalid json object: missing field \'details_json\'') details = StreamInputAnalysis(input_id=input_id, input_path=input_path, details=details_json) return details
def parse_from_json_object(cls, json_object): id_ = json_object.get('id') if id_ is None: raise BitmovinApiError('Invalid json object: missing field \'id\'') position = json_object.get('position') duration = json_object.get('duration') codec = json_object.get('codec') stream = AnalysisStream(id_=id_, position=position, duration=duration, codec=codec) return stream
def parse_from_json_object(cls, json_object): request_id = json_object.get('requestId') if not request_id: raise BitmovinApiError( 'requestId is missing. Maybe the response was not in the specified API format?', json_object) status = json_object.get('status') data = json_object.get('data') response = Response(raw_response=json_object, request_id=request_id, status=status, data=data) return response
def create_without_check(self, object_): response = self.http_client.post(self.relative_url, object_) # type: Response if response.status == Status.ERROR.value: raise BitmovinApiError( 'Response was not successful: {}'.format( response.raw_response), response) if response.status == Status.SUCCESS.value: return None raise InvalidStatusError('Unknown status {} received'.format( response.status))
def retrieve_live(self, encoding_id): self.parsing_utils.check_arg_valid_uuid(encoding_id) url = self.relative_url + '/{}/live'.format(encoding_id) response = self.http_client.get(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_resource_from_response( response=response, class_=EncodingLiveDetails) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def stop_live(self, encoding_id): self.parsing_utils.check_arg_valid_uuid(encoding_id) url = self.relative_url + '/{}/live/stop'.format(encoding_id) response = self.http_client.post_empty_body(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_minimal_model_from_response( response=response) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def list_analyses(self, input_id, offset=0, limit=100): url = '{}/{}/analysis?offset={}&limit={}'.format( self.relative_url, input_id, offset, limit) response = self.http_client.get(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: details_list = self.parsing_utils.parse_bitmovin_resource_list_from_response( response=response, class_=AnalysisDetails) return ResourceResponse(response=response, resource=details_list) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def parse_bitmovin_resource_list_from_response(self, response, class_): response_data = response.data # type: ResponseSuccessData resource_list = response_data.result.get('items') if not isinstance(resource_list, list): raise BitmovinApiError( 'Got invalid response from server: \'items\' has to be a list') resources = [] for resource in resource_list: parsed_resource = class_.parse_from_json_object( json_object=resource) resources.append(parsed_resource) return resources
def filter_by_status(self, status, offset=None, limit=None): if not offset: offset = self.DEFAULT_LIST_OFFSET_PARAM if not limit: limit = self.DEFAULT_LIST_LIMIT_PARAM url = self.BASE_ENDPOINT_URL + '/?status={}&offset={}&limit={}'.format( status.value, offset, limit) response = self.http_client.get(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: models = self.parsing_utils.parse_bitmovin_resource_list_from_response( response=response, class_=self.class_) return ResourceResponse(response=response, resource=models)
def delete(self, id_): self.parsing_utils.check_arg_valid_uuid(argument=id_) url = '{}/{}'.format(self.relative_url, id_) response = self.http_client.delete(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: retrieved_resource = self.parsing_utils.parse_bitmovin_minimal_model_from_response( response=response) return ResourceResponse(response=response, resource=retrieved_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def retrieve_information(self, encoding_id, muxing_id): self.parsing_utils.check_arg_valid_uuid(argument=muxing_id) self.relative_url = self._get_endpoint_url(encoding_id=encoding_id) url = self.relative_url + '/{}/information'.format(muxing_id) response = self.http_client.get(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: retrieved_resource = self.parsing_utils.parse_bitmovin_resource_from_response( response=response, class_=ProgressiveTSInformation) return ResourceResponse(response=response, resource=retrieved_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def _parse_response(self, response): if not check_response_header_json(response): self.logger.error('Response: {}'.format(response.text)) raise BitmovinApiError( 'Response was not in JSON format -> [{}]: {}'.format( response.status_code, response.text), response) success = check_response_success(response) json_response = response.json() if success: parsed_response = self._parse_success_response(json_response) else: self.logger.error('Response had status {}: {}'.format( response.status_code, response.text)) parsed_response = self._parse_error_response(json_response) return parsed_response
def retrieve_analysis_custom_data(self, input_id, analysis_id): self.parsing_utils.check_arg_valid_uuid(argument=input_id) self.parsing_utils.check_arg_valid_uuid(argument=analysis_id) url = '{}/{}/analysis/{}/customData'.format(self.relative_url, input_id, analysis_id) response = self.http_client.get(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: retrieved_resource = self.parsing_utils.parse_bitmovin_resource_from_response( response=response, class_=CustomData) return ResourceResponse(response=response, resource=retrieved_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def list(self, offset=None, limit=None): if not offset: offset = self.DEFAULT_LIST_OFFSET_PARAM if not limit: limit = self.DEFAULT_LIST_LIMIT_PARAM url = '{}?offset={}&limit={}'.format(self.relative_url, offset, limit) response = self.http_client.get(url) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: minimal_models = self.parsing_utils.parse_bitmovin_resource_list_from_response( response=response, class_=self.class_) return ResourceResponse(response=response, resource=minimal_models) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def start_live(self, encoding_id, live_stream_configuration: LiveStreamConfiguration): self.parsing_utils.check_arg_valid_uuid(encoding_id) self.parsing_utils.check_not_none(live_stream_configuration) self.parsing_utils.check_not_blank(live_stream_configuration.streamKey) url = self.relative_url + '/{}/live/start'.format(encoding_id) response = self.http_client.post(url, live_stream_configuration) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_minimal_model_from_response( response=response) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def analyze(self, input_id, analysis_object): if not isinstance(analysis_object, Analysis): raise InvalidTypeError( 'analysis_object has to be an instance of Analysis') response = self.http_client.post(self.relative_url + '/{}/analysis'.format(input_id), analysis_object) # type: Response if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_minimal_model_from_response( response=response) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def start(self, encoding_id, start_encoding_request: StartEncodingRequest = None): self.parsing_utils.check_arg_valid_uuid(encoding_id) url = self.relative_url + '/{}/start'.format(encoding_id) if start_encoding_request is None: response = self.http_client.post_empty_body(relative_url=url) else: response = self.http_client.post(relative_url=url, payload=start_encoding_request) if response.status == Status.ERROR.value: raise BitmovinApiError('Response was not successful', response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_minimal_model_from_response( response=response) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def create(self, object_): if not isinstance(object_, self.class_): raise InvalidTypeError( 'object_ has to be an instance of {}'.format( self.class_.__name__)) response = self.http_client.post(self.relative_url, object_) # type: Response if response.status == Status.ERROR.value: raise BitmovinApiError( 'Response was not successful: {}'.format( response.raw_response), response) if response.status == Status.SUCCESS.value: created_resource = self.parsing_utils.parse_bitmovin_resource_from_response( response=response, class_=self.class_) return ResourceResponse(response=response, resource=created_resource) raise InvalidStatusError('Unknown status {} received'.format( response.status))
def wait_until_finished(self, encoding_id, check_interval=5): status_response = None encoding_status = EncodingStatus(None) while encoding_status.status != 'FINISHED' and encoding_status.status != 'ERROR': status_response = self.status(encoding_id=encoding_id) encoding_status = status_response.resource # type: EncodingStatus self.logger.info("Encoding status: {}".format( encoding_status.status)) self.logger.info( "Will check again in {} seconds...".format(check_interval)) time.sleep(check_interval) self.logger.info("Encoding Status: {}".format( json.dumps(obj=encoding_status, cls=BitmovinJSONEncoder))) if encoding_status.status == 'FINISHED': return True raise BitmovinApiError( "Encoding with ID '{}' was not successfull! Status: {}".format( encoding_id, encoding_status.status), status_response)