Example #1
0
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))
Example #2
0
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()