def create_live_output(client, resource_group_name, account_name, live_event_name, live_output_name, asset_name, archive_window_length, manifest_name=None, description=None, fragments_per_ts_segment=None, output_snap_time=None): from azure.mgmt.media.models import (Hls) if fragments_per_ts_segment is not None: fragments_per_ts_segment = Hls( fragments_per_ts_segment=fragments_per_ts_segment) return client.begin_create(resource_group_name=resource_group_name, account_name=account_name, live_event_name=live_event_name, live_output_name=live_output_name, parameters=LiveOutput( asset_name=asset_name, manifest_name=manifest_name, archive_window_length=archive_window_length, description=description, hls=fragments_per_ts_segment, output_snap_time=output_snap_time))
async def main(): async with client: time_start = time.perf_counter() client_live = await client.live_events.begin_create( resource_group_name=resource_group, account_name=account_name, live_event_name=live_event_name, parameters=live_event_create, auto_start=False) time_end = time.perf_counter() execution_time = (time_end - time_start) if client_live: print( f"Live Event Created - long running operation complete! Name: {live_event_name}" ) print( f"Execution time to create LiveEvent: {execution_time:.2f}seconds" ) print() poller = client_live print(await poller.result()) else: raise ValueError('Live Event creation failed!') # Create an Asset for the LiveOutput to use. Think of this as the "tape" that will be recorded to. # The asset entity points to a folder/container in your Azure Storage account. print(f"Creating an asset named: {asset_name}") print() out_alternate_id = f'outputALTid-{uniqueness}' out_description = f'outputdescription-{uniqueness}' # Create an output asset object out_asset = Asset(alternate_id=out_alternate_id, description=out_description) # Create an output asset output_asset = await client.assets.create_or_update( resource_group, account_name, asset_name, out_asset) if output_asset: # print output asset name print(f"The output asset name is: {output_asset.name}") print() else: raise ValueError('Output Asset creation failed!') # Create the Live Output - think of this as the "tape recorder for the live event". # Live outputs are optional, but are required if you want to archive the event to storage, # use the asset for on-demand playback later, or if you want to enable cloud DVR time-shifting. # We will use the asset created above for the "tape" to record to. manifest_name = "output" # See the REST API for details on each of the settings on Live Output # https://docs.microsoft.com/rest/api/media/liveoutputs/create print(f"Creating a live output named: {live_output_name}") print() if output_asset: time_start = time.perf_counter() live_output_create = LiveOutput( description= "Optional description when using more than one live output", asset_name=output_asset.name, manifest_name= manifest_name, # The HLS and DASH manifest file name. This is recommended to set if you want a deterministic manifest path up front. archive_window_length=timedelta( hours=1 ), # Sets an one hour time-shift DVR window. Uses ISO 8601 format string. hls=Hls(fragments_per_ts_segment= 1 # Advanced setting when using HLS TS output only. )) print(f"live_output_create object is {live_output_create}") print() # Create and await the live output live_output_await = await client.live_outputs.begin_create( resource_group_name=resource_group, account_name=account_name, live_event_name=live_event_name, live_output_name=live_output_name, parameters=live_output_create) if live_output_await: print(f"Live Output created: {live_output_name}") poller = live_output_await print(await poller.result()) time_end = time.perf_counter() execution_time = time_end - time_start print( f"Execution time to create LiveEvent: {execution_time:.2f}seconds" ) print() else: raise Exception("Live Output creation failed!") # Refresh the LiveEvent object's settings after starting it... live_event = await client.live_events.get(resource_group, account_name, live_event_name) # Get the RTMP ingest URL to configure in OBS Studio # The endpoints is a collection of RTMP primary and secondary, and RTMPS primary and secondary URLs. # to get the primary secure RTMPS, it is usually going to be index 3, but you could add a loop here to confirm... if live_event.input.endpoints: ingest_url = live_event.input.endpoints[0].url print("The RTMP ingest URL to enter into OBS Studio is:") print(f"RTMP ingest: {ingest_url}") print( "Make sure to enter a Stream Key into the OBS studio settings. It can be any value or you can repeat the accessToken used in the ingest URL path." ) print() if live_event.preview.endpoints: # Use the preview_endpoint to preview and verify # that the input from the encoder is actually being received # The preview endpoint URL also support the addition of various format strings for HLS (format=m3u8-cmaf) and DASH (format=mpd-time-cmaf) for example. # The default manifest is Smooth. preview_endpoint = live_event.preview.endpoints[0].url print(f"The preview url is: {preview_endpoint}") print() print( "Open the live preview in your browser and use any DASH and HLS player to monitor the preview playback." ) print( f"https://ampdemo.azureedge.net/?url={preview_endpoint}(format=mpd-time-cmaf)&heuristicprofile=lowlatency" ) print( "You will need to refresh the player page SEVERAL times until enough data has arrived to allow for manifest creation." ) print( "In a production player, the player can inspect the manifest to see if it contains enough content for the player to load and auto reload." ) print() print( "Start the live stream now, sending the input to the ingest url and verify that it is arriving with the preview url." ) print( "IMPORTANT TIP!: Make CERTAIN that the video is flowing to the Preview URL before continuing!" ) # Create the Streaming Locator URL for playback of the contents in the Live Output recoding print(f"Creating a streaming locator named: {streaming_locator_name}") print() streaming_locator = StreamingLocator( asset_name=asset_name, streaming_policy_name="Predefined_ClearStreamingOnly") locator = await client.streaming_locators.create( resource_group_name=resource_group, account_name=account_name, streaming_locator_name=streaming_locator_name, parameters=streaming_locator) # Get the default streaming endpoint on the account streaming_endpoint = await client.streaming_endpoints.get( resource_group_name=resource_group, account_name=account_name, streaming_endpoint_name=streaming_endpoint_name) if streaming_endpoint.resource_state != "Running": print( f"Streaming endpoint is stopped. Starting the endpoint named {streaming_endpoint_name}..." ) poller = await client.streaming_endpoints.begin_start( resource_group, account_name, streaming_endpoint_name) client_streaming_begin = await poller.result() print("Streaming Endpoint started.") if not client_streaming_begin: print("Streaming Endpoint was already started.") # Get the URL to stream the Output print( "The streaming URLs to stream the live output from a client player" ) print() host_name = streaming_endpoint.host_name scheme = 'https' # If you wish to get the streaming manifest ahead of time, make sure to set the manifest name in the LiveOutput as done above. # This allows you to have a deterministic manifest path. <streaming endpoint hostname>/<streaming locator ID>/manifestName.ism/manifest(<format string>) # Building the paths statically. Which is highly recommended when you want to share the stream manifests # to a player application or CMS system ahead of the live event. hls_format = "format=m3u8-cmaf" dash_format = "format=mpd-time-cmaf" manifest_base = f"{scheme}://{host_name}/{locator.streaming_locator_id}/{manifest_name}.ism/manifest" hls_manifest = f'{manifest_base}({hls_format})' print(f"The HLS (MP4) manifest URL is: {hls_manifest}") print( "Open the following URL to playback the live stream in an HLS compliant player (HLS.js, Shaka, ExoPlayer) or directly in an iOS device" ) print({hls_manifest}) print() dash_manifest = f'{manifest_base}({dash_format})' print(f"The DASH manifest URL is: {dash_manifest}") print( "Open the following URL to playback the live stream from the LiveOutput in the Azure Media Player" ) print( f"https://ampdemo.azureedge.net/?url={dash_manifest}&heuristicprofile=lowlatency" ) print() # closing media client print('Closing media client') await client.close() # closing credential client print('Closing credential client') await default_credential.close()