Beispiel #1
0
def script_qualifier_settings(props, rtgg_obs: RacetimeObs):
    lang = gettext.translation("racetime-obs",
                               localedir=os.environ['LOCALEDIR'])
    _ = lang.gettext

    p = obs.obs_properties_add_bool(
        props, "use_qualifier",
        _("Display race results as tournament qualifier?"))
    obs.obs_property_set_modified_callback(p, qualifier_toggled)
    qualifier_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, "qualifier_group", _("Qualifier Mode"),
                                 obs.OBS_GROUP_NORMAL, qualifier_group)
    obs.obs_property_set_visible(
        obs.obs_properties_get(props, "qualifier_group"),
        rtgg_obs.qualifier.enabled)
    p = obs.obs_properties_add_int_slider(qualifier_group, "qualifier_cutoff",
                                          _("Use Top X as par time, where X="),
                                          3, 10, 1)
    p = obs.obs_properties_add_list(qualifier_group, "qualifier_par_source",
                                    _("Qualifier Par Time Source"),
                                    obs.OBS_COMBO_TYPE_EDITABLE,
                                    obs.OBS_COMBO_FORMAT_STRING)
    fill_source_list(p)
    p = obs.obs_properties_add_list(qualifier_group, "qualifier_score_source",
                                    _("Qualifier Score Source"),
                                    obs.OBS_COMBO_TYPE_EDITABLE,
                                    obs.OBS_COMBO_FORMAT_STRING)
    fill_source_list(p)
Beispiel #2
0
def script_coop_settings(props, rtgg_obs: RacetimeObs):
    lang = gettext.translation("racetime-obs",
                               localedir=os.environ['LOCALEDIR'])
    _ = lang.gettext

    p = obs.obs_properties_add_bool(props, "use_coop",
                                    _("Display coop information?"))
    obs.obs_property_set_modified_callback(p, coop_toggled)
    coop_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, "coop_group", _("Co-op Mode"),
                                 obs.OBS_GROUP_NORMAL, coop_group)
    obs.obs_property_set_visible(obs.obs_properties_get(props, "coop_group"),
                                 rtgg_obs.coop.enabled)
    p = obs.obs_properties_add_list(coop_group, "coop_partner",
                                    _("Co-op Partner"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    p = obs.obs_properties_add_list(coop_group, "coop_opponent1",
                                    _("Co-op Rival 1"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    p = obs.obs_properties_add_list(coop_group, "coop_opponent2",
                                    _("Co-op Rival 2"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    fill_coop_entrant_lists(props, rtgg_obs)
    p = obs.obs_properties_add_list(coop_group, "coop_our_source",
                                    _("Our Team's Timer"),
                                    obs.OBS_COMBO_TYPE_EDITABLE,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_long_description(p, (
        _("This text source will display your team's timer when you finish.")))
    fill_source_list(p)
    p = obs.obs_properties_add_list(coop_group, "coop_opponent_source",
                                    "Rival Team's Timer",
                                    obs.OBS_COMBO_TYPE_EDITABLE,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_long_description(
        p,
        (_("This text source will be use to display your rival's timer when "
           "they finish")))
    obs.obs_properties_add_color(coop_group, "coop_winner_color",
                                 _("Winner Color:"))
    obs.obs_properties_add_color(coop_group, "coop_loser_color",
                                 _("Loser Color:"))
    obs.obs_properties_add_color(coop_group, "coop_undetermined_color",
                                 _("Winner Undetermined Color"))
    fill_source_list(p)
Beispiel #3
0
def script_ladder_settings(props):
    ladder_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, lp.ladder_group, _("Ladder Settings"),
                                 obs.OBS_GROUP_NORMAL, ladder_group)
    p = obs.obs_properties_add_text(ladder_group, lp.ladder_name,
                                    _("Ladder Name"), obs.OBS_TEXT_DEFAULT)
    obs.obs_property_set_modified_callback(p, name_modified)
    obs.obs_properties_add_color(ladder_group, lp.pre_color,
                                 _("Color Pre-Race"))
    obs.obs_properties_add_color(ladder_group, lp.racing_color,
                                 _("Still Racing Color"))
    obs.obs_properties_add_color(ladder_group, lp.winner_color,
                                 _("Winner Color"))
    obs.obs_properties_add_color(ladder_group, lp.loser_color,
                                 _("Loser Color"))
    obs.obs_properties_add_color(ladder_group, lp.ff_color, _("Forfeit Color"))
    p = obs.obs_properties_add_list(ladder_group, lp.stats_source,
                                    _("Ladder Stats Source"),
                                    obs.OBS_COMBO_TYPE_EDITABLE,
                                    obs.OBS_COMBO_FORMAT_STRING)
    fill_source_list(p)
    obs.obs_properties_add_bool(ladder_group, lp.show_season_name,
                                _("Show Season Name"))
    obs.obs_properties_add_bool(ladder_group, lp.show_mode_name,
                                _("Show Mode Name"))
    obs.obs_properties_add_bool(ladder_group, lp.show_rating, _("Show Rating"))
    obs.obs_properties_add_bool(ladder_group, lp.show_rank, _("Show Rank"))
    obs.obs_properties_add_bool(ladder_group, lp.show_change, _("Show Change"))
    obs.obs_properties_add_bool(ladder_group, lp.show_win_loss_tie,
                                _("Show Win/Loss/Tie Record"))
    p = obs.obs_properties_add_list(ladder_group, lp.ladder_season,
                                    _("Season for Stats"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_modified_callback(p, season_or_mode_changed)
    obs.obs_property_list_add_string(p, _("Lifetime"), "0")
    obs.obs_property_list_add_string(p, _("Current Season"), "-1")
    p = obs.obs_properties_add_list(ladder_group, lp.ladder_mode,
                                    _("Mode for Stats"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_modified_callback(p, season_or_mode_changed)
    obs.obs_property_list_add_string(p, _("Global"), "0")
    obs.obs_property_list_add_string(p, _("Current Mode"), "-1")
Beispiel #4
0
 def _add(self, props, on_changed):
     flags = _obs.OBS_GROUP_NORMAL
     if self.checkable:
         flags = _obs.OBS_GROUP_CHECKABLE
     p = _obs.obs_properties_create()
     for e in self.elements:
         e._add(p, on_changed)
     g = _obs.obs_properties_add_group(props, self.name, self.text, flags,
                                       p)
     super()._add(g, on_changed)
Beispiel #5
0
def script_media_player_settings(props, rtgg_obs: RacetimeObs,
                                 media_player_toggled):
    lang = gettext.translation("racetime-obs",
                               localedir=os.environ['LOCALEDIR'])
    _ = lang.gettext

    p = obs.obs_properties_add_bool(props, "use_media_player",
                                    _("Enable sounds?"))
    obs.obs_property_set_modified_callback(p, media_player_toggled)
    media_player_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, "media_player_group",
                                 _("Media Player Mode"), obs.OBS_GROUP_NORMAL,
                                 media_player_group)
    obs.obs_property_set_visible(
        obs.obs_properties_get(props, "media_player_group"),
        rtgg_obs.media_player.enabled)
    monitoring_list = obs.obs_properties_add_list(media_player_group,
                                                  "monitoring_type",
                                                  _("Monitoring Type"),
                                                  obs.OBS_COMBO_TYPE_LIST,
                                                  obs.OBS_COMBO_FORMAT_INT)
    obs.obs_property_list_add_int(monitoring_list, _("Listen Only"),
                                  obs.OBS_MONITORING_TYPE_MONITOR_ONLY)
    obs.obs_property_list_add_int(monitoring_list, _("Stream Only"),
                                  obs.OBS_MONITORING_TYPE_NONE)
    obs.obs_property_list_add_int(monitoring_list, _("Listen and Stream"),
                                  obs.OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT)
    p = obs.obs_properties_add_bool(media_player_group, "use_chat_pings",
                                    _("Chat Pings"))
    obs.obs_property_set_long_description(
        p,
        _("Enable this and set choose a sound file to play when a bot posts"
          " or when someone @s you in racetime.gg chat"))
    p = obs.obs_properties_add_path(media_player_group, "chat_ping_sound",
                                    _("Chat media file"), obs.OBS_PATH_FILE,
                                    "Audio Files (*.mp3 *.aac *.wav *.wma)",
                                    None)
    obs.obs_properties_add_path(media_player_group, "first_place_sound",
                                _("First Place Sound"), obs.OBS_PATH_FILE,
                                "Audio Files (*.mp3 *.aac *.wav *.wma)", None)
    obs.obs_property_set_long_description(
        p, _("Sound file to play when you finish first."))
Beispiel #6
0
def script_timer_settings(props, rtgg_obs: RacetimeObs):
    lang = gettext.translation("racetime-obs",
                               localedir=os.environ['LOCALEDIR'])
    _ = lang.gettext

    p = obs.obs_properties_add_bool(props, "use_podium",
                                    _("Use custom color for podium finishes?"))
    obs.obs_property_set_modified_callback(p, podium_toggled)
    podium_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, "podium_group", _("Podium Colors"),
                                 obs.OBS_GROUP_NORMAL, podium_group)
    obs.obs_property_set_visible(obs.obs_properties_get(props, "podium_group"),
                                 rtgg_obs.timer.use_podium_colors)
    obs.obs_properties_add_color(podium_group, "pre_color", _("Pre-race:"))
    obs.obs_properties_add_color(podium_group, "racing_color",
                                 _("Still racing:"))
    obs.obs_properties_add_color(podium_group, "first_color", _("1st place:"))
    obs.obs_properties_add_color(podium_group, "second_color", _("2nd place:"))
    obs.obs_properties_add_color(podium_group, "third_color", _("3rd place:"))
    obs.obs_properties_add_color(podium_group, "finished_color",
                                 _("After podium:"))
Beispiel #7
0
def media_trigger_settings(props, rtgg_obs: RacetimeObs, index: int):
    lang = gettext.translation("racetime-obs",
                               localedir=os.environ['LOCALEDIR'])
    _ = lang.gettext

    media_player_group = obs.obs_properties_create()
    name = f"media_trigger_#{index}"
    obs.obs_properties_add_group(props, name,
                                 _("Media Trigger #") + f"{index}",
                                 obs.OBS_GROUP_NORMAL, media_player_group)
    obs.obs_property_set_visible(
        obs.obs_properties_get(props, "media_player_group"),
        rtgg_obs.media_player.enabled)
    obs.obs_properties_add_path(media_player_group, f"media_path_#{index}",
                                _("Sound File"), obs.OBS_PATH_FILE,
                                "Audio Files (*.mp3 *.aac *.wav *.wma)", None)
    p = obs.obs_properties_add_list(media_player_group,
                                    f"trigger_type_#{index}",
                                    _("Type of Trigger"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_list_add_string(p, "", "")
    obs.obs_property_list_add_string(p, _("Chat"), "chat")
    obs.obs_property_list_add_string(p, _("Finish Place"), "finish")
    obs.obs_property_list_add_string(p, _("Timer"), "time")
    obs.obs_property_set_modified_callback(p, media_type_changed)
    p = obs.obs_properties_add_list(media_player_group,
                                    f"monitoring_type_#{index}",
                                    _("Monitoring Type"),
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_INT)
    obs.obs_property_list_add_int(p, _("Only Listen"),
                                  obs.OBS_MONITORING_TYPE_MONITOR_ONLY)
    obs.obs_property_list_add_int(p, _("Only Stream"),
                                  obs.OBS_MONITORING_TYPE_NONE)
    obs.obs_property_list_add_int(p, _("Listen and Stream"),
                                  obs.OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT)
Beispiel #8
0
def script_properties():  # OBS script interface.
    props = obs.obs_properties_create()

    grp = obs.obs_properties_create()
    p = obs.obs_properties_add_bool(grp, 'help', 'Help')
    obs.obs_property_set_enabled(p, False)
    obs.obs_property_set_long_description(
        p,
        '''<p>This script automatically maps Discord video calls into the scene’s layout.</p>
<h3>Discord instructions</h3>
<ol>
  <li>In the voice channel where the call is happening, go to the bottom-right corner and select <em>Pop Out.</em></li>
  <li>In the top-right corner, ensure you’re in <em>Grid</em> mode (no caller appears big while the rest are small).</li>
</ol>

<h3>OBS capture source and scene set-up</h3>
<ol>
  <li>Create a <em>Window Capture</em> source and set it to capture your Discord call.</li>
  <li>Move and crop it until it’s the size and position you want a single caller’s video to be in the scene— don’t pay any attention to which area of the Discord call it shows, as that’s what this script does for you.</li>
  <li>Duplicate it <strong>(always as reference)</strong> and tweak it for every other caller, across scenes, etc.</li>
  <li>Make sure the order of all Discord items in the <em>Sources</em> panel matches across your scenes, with the order in which you want the participants to show up (see next section).</li>
</ol>

<h3>Using this script</h3>
<ol>
  <li>Clicking on <em>Bot invite link</em> will take to a Discord webpage where you can invite your bot to any of your servers with the right permissions, or you can copy the URL and share it with someone who owns another server too.</li>
  <li>Open the dropdown menu below, and pick the voice channel you’re in.</strong></li>
  <li>Tick the <em>Full Screen</li> and <em>Show Non-Video Participants</em> checkboxes according to the state of your Discord call (on Discord, <em>Show Non-Video Participants</em> is located under the three dots button at the top right of the call window).</li>
  <li>Open the next dropdown menu, and pick the source that’s capturing the Discord call. <strong>CAUTION: this will irreversibly modify all items belonging to the source you pick! Moreover, the script knows which items to modify based on their source’s name alone, so please avoid changing your sources’ names to prevent unexpected behaviour.</strong></li>
  <li>If <em>Show Non-Video Participants</em> is off, you can tick <em>Show/hide item right below for audio-only.</em> This requires an item right below each Discord item, which the script will show when the participant has no video, and hide otherwise.</li>
  <li>Pick yourself in the <em>Myself</em> list, so that you appear un-mirrored to the rest of the world while your video is on.</li>
  <li>Choose every participant you want to appear in your scene. Follow the same order you used with your Discord items in the <em>Sources</em> panel.</li>
  <li><strong>If you’re in <em>Studio Mode,</em> click on the gear icon between both views, and make sure <em>Duplicate Scene</em> is OFF!</strong></li>
</ol>''')

    p = obs.obs_properties_add_button(grp, 'bot_invite_link',
                                      'Bot invite link', bot_invite)
    obs.obs_property_set_long_description(
        p,
        '<p>Go to a Discord webpage that lets you invite your bot into any of your servers with the right permissions. You can share this URL with the owner of another server so they invite it for you.</p>'
    )

    p = obs.obs_properties_add_list(grp, 'voice_channel', 'Voice channel',
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_modified_callback(p, populate_participants)
    obs.obs_property_set_long_description(
        p,
        '<p>Discord server and voice/video channel where the call is happening.</p>'
    )
    p = obs.obs_properties_add_button(grp, 'refresh_channels',
                                      'Refresh channels', populate_channels)
    obs.obs_property_set_long_description(
        p,
        '<p>Rebuild the list of channels above. Useful for when you’ve just invited the bot to a server, or a new channel has been created in one of the servers it’s invited to. Don’t worry— it won’t reset your choice, unless it’s no longer available.</p>'
    )

    p = obs.obs_properties_add_bool(grp, 'full_screen', 'Full-screen')
    obs.obs_property_set_long_description(
        p,
        '<p>Whether the Discord call window is in <em>Full Screen</em> mode</p>'
    )
    p = obs.obs_properties_add_bool(grp, 'show_nonvideo_participants',
                                    'Show Non-Video Participants')
    obs.obs_property_set_modified_callback(
        p, show_nonvideo_participants_callback)
    obs.obs_property_set_long_description(
        p,
        '<p>Whether the Discord call window has <em>Show Non-video Participants</em> on (under the three dots button at the top right corner)</p>'
    )

    p = obs.obs_properties_add_list(grp, 'discord_source', 'Discord source',
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_long_description(
        p,
        '<p>Source that is capturing the Discord call. <strong>CAUTION: this will irreversibly modify all items belonging to the source you pick!</strong></p>'
    )
    p = obs.obs_properties_add_button(grp, 'refresh_sources',
                                      'Refresh sources', populate_sources)
    obs.obs_property_set_long_description(
        p,
        '<p>Rebuild the list of sources above. Useful for when you’ve made major changes to your scenes. This won’t reset your choice, unless it’s no longer available.</p>'
    )
    p = obs.obs_properties_add_bool(
        grp, 'item_right_below', 'Show/hide item right below for audio-only')
    obs.obs_property_set_long_description(
        p,
        '<p>Requires an item right below each Discord item, which the script will show when the participant has no video, and hide otherwise</p>'
    )

    obs.obs_properties_add_group(props, 'general', 'General',
                                 obs.OBS_GROUP_NORMAL, grp)

    grp = obs.obs_properties_create()
    p = obs.obs_properties_add_list(grp, 'myself', 'Myself',
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_long_description(
        p, '<p>Participant whose video should be un-mirrored (yourself).</p>')
    p = obs.obs_properties_add_button(grp, 'refresh_names', 'Refresh names',
                                      populate_participants)
    obs.obs_property_set_long_description(
        p,
        '<p>Rebuild the participant lists. Useful when there have been nickname changes, or someone has joined the server. Don’t worry— it won’t reset each choice, unless a selected participant left the server.</p>'
    )
    for i in range(SLOTS):
        p = obs.obs_properties_add_list(grp, f'participant{i}', None,
                                        obs.OBS_COMBO_TYPE_LIST,
                                        obs.OBS_COMBO_FORMAT_STRING)
        obs.obs_property_set_long_description(
            p, '<p>Participant to appear at the ' + ordinal(i + 1) +
            ' capture item from the top of the scene</p>')
    obs.obs_properties_add_group(props, 'participant_layout',
                                 'Participant layout', obs.OBS_GROUP_NORMAL,
                                 grp)

    populate_sources(props)
    while not client.is_ready():
        time.sleep(0.1)
    populate_channels(props)
    populate_participants(props)

    obs.obs_properties_apply_settings(props, settings)
    return props
def script_properties():
    props = obs.obs_properties_create()

    p = obs.obs_properties_add_bool(props, "manage_streaming",
                                    "Manage Streaming")
    obs.obs_property_set_modified_callback(p, on_property_modified)
    p = obs.obs_properties_add_bool(props, "manage_recording",
                                    "Manage Recording")
    obs.obs_property_set_modified_callback(p, on_property_modified)

    auto_start_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, "auto_start_group", "Auto Start",
                                 obs.OBS_GROUP_NORMAL, auto_start_group)

    p = obs.obs_properties_add_list(auto_start_group, "start_scene",
                                    "Start Scene", obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_enabled(p, manage_streaming or manage_recording)
    obs.obs_property_set_modified_callback(p, on_property_modified)
    obs.obs_property_list_add_string(p, "--Disabled--", "")
    scene_names = obs.obs_frontend_get_scene_names()
    if scene_names != None:
        for scene_name in scene_names:
            obs.obs_property_list_add_string(p, scene_name, scene_name)

    schedule_group = obs.obs_properties_create()
    obs.obs_properties_add_group(auto_start_group, "schedule_group",
                                 "Schedule", obs.OBS_GROUP_NORMAL,
                                 schedule_group)

    p = obs.obs_properties_add_list(schedule_group, "weekday", "Day of Week",
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_INT)
    obs.obs_property_set_enabled(p, (manage_streaming or manage_recording)
                                 and start_scene != "")
    for i, day_of_week in enumerate(days_of_week):
        obs.obs_property_list_add_int(p, day_of_week, i)

    p = obs.obs_properties_add_list(schedule_group, "preshow_duration",
                                    "Livestream Start",
                                    obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_INT)
    obs.obs_property_set_enabled(p, (manage_streaming or manage_recording)
                                 and start_scene != "")
    obs.obs_property_list_clear(p)
    for i in range(4):
        seconds = i * 60 * 5
        obs.obs_property_list_add_int(
            p,
            time(hour=math.floor((event_start - seconds) / 60 / 60),
                 minute=int(
                     (event_start - seconds) / 60 % 60)).strftime("%I:%M %p"),
            seconds)

    p = obs.obs_properties_add_list(schedule_group, "event_start",
                                    "Event Start", obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_INT)
    obs.obs_property_set_enabled(p, (manage_streaming or manage_recording)
                                 and start_scene != "")
    obs.obs_property_set_modified_callback(p, event_start_list_modified)
    for i in range(288):
        obs.obs_property_list_add_int(
            p,
            time(hour=math.floor(i / 12),
                 minute=(i % 12) * 5).strftime("%I:%M %p"),
            int((i / 12) * 60 * 60))

    text_source_list = obs.obs_properties_add_list(auto_start_group,
                                                   "text_source",
                                                   "Text Source",
                                                   obs.OBS_COMBO_TYPE_LIST,
                                                   obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_enabled(text_source_list,
                                 (manage_streaming or manage_recording)
                                 and start_scene != "")
    obs.obs_property_set_modified_callback(text_source_list,
                                           on_property_modified)
    obs.obs_property_list_add_string(text_source_list, "--Disabled--", "")

    sources = obs.obs_enum_sources()
    if sources != None:
        for source in sources:
            source_id = obs.obs_source_get_unversioned_id(source)
            if source_id == "text_gdiplus" or source_id == "text_ft2_source":
                name = obs.obs_source_get_name(source)
                obs.obs_property_list_add_string(text_source_list, name, name)
    obs.source_list_release(sources)

    p = obs.obs_properties_add_text(auto_start_group, "countdown_final_text",
                                    "Countdown Final Text",
                                    obs.OBS_TEXT_DEFAULT)
    obs.obs_property_set_enabled(p, (manage_streaming or manage_recording)
                                 and text_source != "" and start_scene != "")

    auto_stop_group = obs.obs_properties_create()
    obs.obs_properties_add_group(props, "auto_stop_group", "Auto Stop",
                                 obs.OBS_GROUP_NORMAL, auto_stop_group)

    p = obs.obs_properties_add_list(auto_stop_group, "closing_scene",
                                    "Closing Scene", obs.OBS_COMBO_TYPE_LIST,
                                    obs.OBS_COMBO_FORMAT_STRING)
    obs.obs_property_set_enabled(p, manage_streaming or manage_recording)
    obs.obs_property_set_modified_callback(p, closing_scene_modified)
    obs.obs_property_list_add_string(p, "--Disabled--", "")
    scene_names = obs.obs_frontend_get_scene_names()
    if scene_names != None:
        for scene_name in scene_names:
            obs.obs_property_list_add_string(p, scene_name, scene_name)

    p = obs.obs_properties_add_int(auto_stop_group, "stop_streaming_delay",
                                   "Streaming Delay", 0, 300, 15)
    obs.obs_property_set_enabled(p, manage_streaming and closing_scene != "")
    p = obs.obs_properties_add_int(auto_stop_group, "stop_recording_delay",
                                   "Recording Delay", 0, 120, 5)
    obs.obs_property_set_enabled(p, manage_recording and closing_scene != "")

    return props
    def script_properties():
        props = obs.obs_properties_create()

        youtube_props = obs.obs_properties_create()
        obs.obs_properties_add_group(props, 'youtube', 'YouTube',
                                     obs.OBS_GROUP_NORMAL, youtube_props)

        obs.obs_properties_add_text(youtube_props, 'event_name', 'Event Name',
                                    obs.OBS_TEXT_DEFAULT)
        obs.obs_properties_add_text(youtube_props, 'youtube_description',
                                    'YouTube Description',
                                    obs.OBS_TEXT_MULTILINE)
        obs.obs_properties_add_text(youtube_props, 'youtube_category_id',
                                    'YouTube Category ID',
                                    obs.OBS_TEXT_DEFAULT)
        youtube_privacy_status_prop = obs.obs_properties_add_list(
            youtube_props, 'youtube_privacy_status', 'YouTube Privacy Status',
            obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
        obs.obs_property_list_add_string(youtube_privacy_status_prop, 'Public',
                                         'public')
        obs.obs_property_list_add_string(youtube_privacy_status_prop,
                                         'Unlisted', 'unlisted')
        obs.obs_property_list_add_string(youtube_privacy_status_prop,
                                         'Private', 'private')
        obs.obs_properties_add_text(youtube_props, 'youtube_playlist',
                                    'YouTube Playlist', obs.OBS_TEXT_DEFAULT)

        scorekeeper_props = obs.obs_properties_create()
        obs.obs_properties_add_group(props, 'scorekeeper', 'Scorekeeper',
                                     obs.OBS_GROUP_NORMAL, scorekeeper_props)

        obs.obs_properties_add_text(scorekeeper_props, 'event_code',
                                    'Event Code', obs.OBS_TEXT_DEFAULT)
        obs.obs_properties_add_text(scorekeeper_props, 'scorekeeper_api',
                                    'Scorekeeper API', obs.OBS_TEXT_DEFAULT)

        obs.obs_properties_add_button(scorekeeper_props,
                                      'test_scorekeeper_connection',
                                      'Test Scorekeeper Connection',
                                      test_scorekeeper_connection)

        toa_props = obs.obs_properties_create()
        obs.obs_properties_add_group(props, 'toa', 'The Orange Alliance',
                                     obs.OBS_GROUP_NORMAL, toa_props)

        obs.obs_properties_add_text(toa_props, 'toa_key', 'TOA Key',
                                    obs.OBS_TEXT_PASSWORD)
        obs.obs_properties_add_text(toa_props, 'toa_event', 'TOA Event Code',
                                    obs.OBS_TEXT_DEFAULT)

        google_props = obs.obs_properties_create()
        obs.obs_properties_add_group(props, 'google', 'Google API',
                                     obs.OBS_GROUP_NORMAL, google_props)

        obs.obs_properties_add_text(google_props, 'google_project_id',
                                    'Google API Project ID',
                                    obs.OBS_TEXT_DEFAULT)
        obs.obs_properties_add_text(google_props, 'google_client_id',
                                    'Google API Client ID',
                                    obs.OBS_TEXT_DEFAULT)
        obs.obs_properties_add_text(google_props, 'google_client_secret',
                                    'Google API Client Secret',
                                    obs.OBS_TEXT_PASSWORD)

        obs.obs_properties_add_button(google_props,
                                      'refresh_google_authentication',
                                      'Refresh Google Authentication',
                                      refresh_google_authentication)
        obs.obs_properties_add_button(google_props,
                                      'delete_google_authentication',
                                      'Delete Google Authentication',
                                      delete_google_authentication)

        recording_props = obs.obs_properties_create()
        obs.obs_properties_add_group(props, 'recording', 'Recording',
                                     obs.OBS_GROUP_NORMAL, recording_props)

        video_encoder_prop = obs.obs_properties_add_list(
            recording_props, 'video_encoder', 'Video Encoder (H.264)',
            obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
        obs.obs_property_list_add_string(video_encoder_prop, 'x264',
                                         'obs_x264')
        if obs.obs_encoder_get_display_name('jim_nvenc'):
            obs.obs_property_list_add_string(video_encoder_prop, 'NVENC',
                                             'jim_nvenc')
        elif obs.obs_encoder_get_display_name('ffmpeg_nvenc'):
            obs.obs_property_list_add_string(video_encoder_prop, 'NVENC',
                                             'ffmpeg_nvenc')
        if obs.obs_encoder_get_display_name('amd_amf_h264'):
            obs.obs_property_list_add_string(video_encoder_prop, 'AMF',
                                             'amd_amf_h264')
        if obs.obs_encoder_get_display_name('obs_qsv11'):
            obs.obs_property_list_add_string(video_encoder_prop, 'QuickSync',
                                             'obs_qsv11')
        obs.obs_properties_add_int(recording_props, 'video_bitrate',
                                   'Video Bitrate', 0, 24000, 50)
        audio_encoder_prop = obs.obs_properties_add_list(
            recording_props, 'audio_encoder', 'Audio Encoder (AAC)',
            obs.OBS_COMBO_TYPE_LIST, obs.OBS_COMBO_FORMAT_STRING)
        obs.obs_property_list_add_string(audio_encoder_prop, 'FFmpeg',
                                         'ffmpeg_aac')
        if obs.obs_encoder_get_display_name('mf_aac'):
            obs.obs_property_list_add_string(audio_encoder_prop,
                                             'MediaFoundation', 'mf_aac')
        if obs.obs_encoder_get_display_name('libfdk_aac'):
            obs.obs_property_list_add_string(audio_encoder_prop,
                                             'Fraunhofer FDK', 'libfdk_aac')
        if obs.obs_encoder_get_display_name('CoreAudio_AAC'):
            obs.obs_property_list_add_string(audio_encoder_prop, 'CoreAudio',
                                             'CoreAudio_AAC')
        obs.obs_properties_add_int(recording_props, 'audio_bitrate',
                                   'Audio Bitrate', 0, 2000, 1)

        match_props = obs.obs_properties_create()
        obs.obs_properties_add_group(props, 'match',
                                     'Match (Internal Settings)',
                                     obs.OBS_GROUP_NORMAL, match_props)

        match_type_prop = obs.obs_properties_add_list(
            match_props, 'match_type', 'Match Type', obs.OBS_COMBO_TYPE_LIST,
            obs.OBS_COMBO_FORMAT_STRING)
        obs.obs_property_list_add_string(match_type_prop, 'Qualification',
                                         'qualification')
        obs.obs_property_list_add_string(match_type_prop, 'Semi-Final',
                                         'semi-final')
        obs.obs_property_list_add_string(match_type_prop, 'Final', 'final')
        obs.obs_properties_add_int(match_props, 'match_pair', 'Match Pair', 1,
                                   2, 1)
        obs.obs_properties_add_int(match_props, 'match_number', 'Match Number',
                                   1, 50, 1)
        obs.obs_properties_add_int(match_props, 'match_code', 'Match Code', 1,
                                   50, 1)

        obs.obs_properties_add_button(match_props, 'reset_match_info',
                                      'Reset Match Info', reset_match_info)

        return props