# wpstream/4.12.4/templates/broadcaster-template.php

WpStream – Live Streaming, Video on Demand, Pay Per View, version 4.12.4. 197 lines.

- Page: https://pluginprobe.com/plugins/wpstream/4.12.4/code/templates/broadcaster-template.php
- Raw: https://pluginprobe.com/plugins/wpstream/4.12.4/raw/templates/broadcaster-template.php
- Modified: 2026-02-26T06:59:50+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/wpstream/4.12.4/code/templates/broadcaster-template.php#L10-L20`.

```php
<?php
/**
 * Template Name: WPStream OvenLiveKit Broadcaster
 */

// Security check
if (!defined('ABSPATH')) {
	exit;
}

// Only allow logged-in users with appropriate permissions
if (!is_user_logged_in() || !current_user_can('publish_posts')) {
	wp_die(__('You do not have sufficient permissions to access this page.', 'wpstream'));
}

// Get channel ID from URL parameter
$channel_id = get_query_var('channel_id');
if (empty($channel_id)) {
	wp_die(__('No channel ID specified.', 'wpstream'));
}

// Get stream information from post meta
$obs_uri = get_post_meta($channel_id, 'obs_uri', true);
$obs_stream = get_post_meta($channel_id, 'obs_stream', true);
$whip_url = get_post_meta($channel_id, 'whipUrl', true);

$onboarding    = isset( $_GET['onboarding'] ) ? sanitize_text_field( wp_unslash( $_GET['onboarding'] ) ) : '';
$is_onboarding = ( $onboarding === '1' );

if (empty($whip_url)) {
	wp_die(__('WHIP URL not available for this channel.', 'wpstream'));
}

wp_enqueue_style(
	'wpstream-broadcaster-css',
	WPSTREAM_PLUGIN_DIR_URL . 'public/css/broadcaster.css',
	array(),
	filemtime(WPSTREAM_PLUGIN_PATH . 'public/css/broadcaster.css')
);

wp_enqueue_script(
	'wpstream-broadcaster-new',
	WPSTREAM_PLUGIN_DIR_URL . 'public/js/broadcaster.js',
	array(),
	filemtime(WPSTREAM_PLUGIN_PATH . 'public/js/broadcaster.js'),
	true
);

wp_localize_script(
	'wpstream-broadcaster-new',
	'wpstream_broadcaster_vars',
	array(
		'ajax_url'              => admin_url('admin-ajax.php'),
		'nonce'                 => wp_create_nonce('wpstream_broadcaster_nonce'),
		'plugin_url'            => plugin_dir_url(__FILE__),
		'obs_uri'               => $obs_uri,
		'obs_stream'            => $obs_stream,
        'channel_id'            => $channel_id,
		'is_channel_live'       => get_post_meta($channel_id, 'status', true),
		'whip_url'              => get_post_meta($channel_id, 'whipUrl', true),
		'no_video_audio_access' => esc_html__('We couldn’t access your camera or microphone. Please allow permissions and reload the page.', 'wpstream'),
		'no_audio_access'       => esc_html__('We couldn’t access your microphone. Please allow permissions and reload the page.', 'wpstream'),
		'no_video_access'       => esc_html__('We couldn’t access your camera. Please allow permissions and reload the page.', 'wpstream'),
        'channel_off'           => esc_html__('Invalid event. Your live event may have expired or its credentials are incorrect.', 'wpstream'),
        'not_enough_traffic'    => sprintf(
                esc_html__('Not enough streaming traffic to broadcast. Please %supgrade your subscription%s for extra resources.', 'wpstream'),
                '<a href="https://wpstream.net/pricing/" target="_blank">',
                '</a>'
        ),
        'is_onboarding'         => $is_onboarding
	)
);

if ( $is_onboarding ) {
	wp_enqueue_script('wpstream-on-boarding-page-js', plugin_dir_url( __DIR__  ) .'admin/js/wpstream-onboarding-page.js',array(),  WPSTREAM_PLUGIN_VERSION, true);
	wp_localize_script( 'wpstream-on-boarding-page-js', 'wpstream_onboarding_page_vars',
		array(
			'admin_url'      => get_admin_url(),
			'request_url'    => WPSTREAM_CLICK,
			'wps_user'       => get_option('wpstream_api_username_from_token'),
			'current_page'   => 'broadcaster',
			'plugin_version' => WPSTREAM_PLUGIN_VERSION,
		)
	);
}

?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo('charset'); ?>">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<title><?php esc_html_e('WpStream Broadcaster', 'wpstream'); ?></title>

	<?php wp_head(); ?>

	<!-- Load required libraries in correct order -->
	<script src="https://cdn.jsdelivr.net/npm/underscore@1.12.0/underscore-min.js"></script>
	<script src="https://cdn.jsdelivr.net/npm/ovenlivekit@latest/dist/OvenLiveKit.min.js"></script>
</head>
<body class="wpstream-broadcaster-page">
<header class="broadcaster-header">
	<div class="header-container">
		<div class="header-logo">
			<a href="<?php echo esc_url(home_url('/')); ?>">
				<img src="<?php echo esc_url(WPSTREAM_PLUGIN_DIR_URL . 'img/wpstream-logo.svg'); ?>" alt="WpStream Logo">
			</a>
		</div>
		<nav class="header-nav">
			<span class="nav-item">Browser Broadcaster</span>
		</nav>
	</div>
</header>

<div id="messageContainer"></div>

<div class="broadcaster-container">
	<div class="wrapper">
		<div class="video-container">
            <button id="videoExpandToggle" class="video-expand-toggle" type="button" aria-label="<?php esc_attr_e('Toggle Full View', 'wpstream'); ?>" title="<?php esc_attr_e('Toggle Full View', 'wpstream'); ?>">
                <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" y1="3" x2="14" y2="10"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>
            </button>
            <div id="videoLiveIndicator" class="video-live-indicator">
                <span id="videoLiveIndicatorLive" class="badge badge-pill badge-danger" style="display:none;"><?php esc_html_e('LIVE', 'wpstream'); ?></span>
                <span id="videoLiveIndicatorError" class="badge badge-pill badge-warning" style="display:none;"><?php esc_html_e('Connecting...', 'wpstream'); ?></span>
            </div>
            <div class="video-wrapper">
                <div id="wpstream-pre-load-spinner" class="wpstream-pre-load-spinner"></div>
			    <video id="localVideo" autoplay muted playsinline></video>
            </div>
		</div>

		<div class="settings-panel" id="settingsPanel">
			<div>
				<?php
				$ajax_nonce = wp_create_nonce( "wpstream_start_event_nonce" );
				print '<input type="hidden" id="wpstream_start_event_nonce" value="'.$ajax_nonce.'">';
				?>
				<div class="controls-container">
					<button id="startBroadcast" class="button start-broadcast" disabled><?php esc_html_e('Start Broadcast', 'wpstream'); ?></button>
					<button id="stopBroadcast" class="button stop-broadcast hidden"><?php esc_html_e('Stop Broadcast', 'wpstream'); ?></button>
				</div>
				<div class="status-container">
					<div>
						<span class="status-indicator" id="statusIndicator"></span>
						<span id="statusText"><?php esc_html_e('Not connected', 'wpstream'); ?></span>
					</div>
				</div>
			</div>

			<div class="settings-row media-row">
				<div class="settings-group">
					<label for="videoDevice"><?php esc_html_e('Video Source', 'wpstream'); ?></label>
					<div class="controls-group">
						<select id="videoDevice">
							<option selected></option>
						</select>
						<button id="videoToggle" class="control-button">
							<img alt="" class="noll" id="video-off" src="<?php echo esc_url(WPSTREAM_PLUGIN_DIR_URL . 'img/videocam-32px.svg'); ?>">
							<img alt="" class="noll" id="video-on" src="<?php echo esc_url(WPSTREAM_PLUGIN_DIR_URL . 'img/videocam-off-32px.svg'); ?>" style="display:none;">
						</button>
					</div>
				</div>

				<div class="settings-group">
					<label for="audioDevice"><?php esc_html_e('Audio Source', 'wpstream'); ?></label>
                    <div class="controls-group">
                        <select id="audioDevice">
                            <option selected></option>
                        </select>
                        <button id="audioToggle" class="control-button">
                            <img alt="" class="noll" id="audio-off" src="<?php echo esc_url( WPSTREAM_PLUGIN_DIR_URL . 'img/mic-32px.svg' ); ?>">
                            <img alt="" class="noll" id="audio-on" src="<?php echo esc_url( WPSTREAM_PLUGIN_DIR_URL . 'img/mic-off-32px.svg' ); ?>" style="display:none;">
                        </button>
                    </div>
				</div>
			</div>

			<div class="settings-row">
				<div class="settings-group">
					<label for="videoQuality"><?php esc_html_e('Video Resolution', 'wpstream'); ?></label>
					<select id="videoQuality">
						<option selected value="default">Default</option>
						<option value="fhd"><?php esc_html_e('1920x1080', 'wpstream'); ?></option>
						<option value="hd"><?php esc_html_e('1280x720', 'wpstream'); ?></option>
						<option value="square"><?php esc_html_e('800x600', 'wpstream'); ?></option>
						<option value="vga"><?php esc_html_e('640x360', 'wpstream'); ?></option>
					</select>
				</div>
			</div>
		</div>
	</div>
</div>

<?php wp_footer(); ?>
</body>
</html>
```
