Пример #1
0
def script_properties():
    # print('script_properties')

    props = obs.obs_properties_create()

    model_p = obs.obs_properties_add_path(props, 'live2d_model',
                                          'Live2D Model', obs.OBS_PATH_FILE,
                                          'Live2D Model(*.json)', '')

    level_p = obs.obs_properties_add_int(props, 'root_level',
                                         'Server Root Level', 1,
                                         total_levels(LIVE2D_FULL_PATH), 1)

    port_p = obs.obs_properties_add_int(props, 'port', 'Server Port', 1024,
                                        65535, 1)
    ws_port_p = obs.obs_properties_add_int(props, 'ws_port', 'Websocket Port',
                                           1024, 65535, 1)

    info_p = obs.obs_properties_add_text(props, 'info', 'Info',
                                         obs.OBS_TEXT_MULTILINE)
    obs.obs_property_set_enabled(info_p, False)

    obs.obs_properties_add_button(props, 'start', 'Apply Settings',
                                  apply_settings)

    obs.obs_property_set_modified_callback(model_p, prop_modified)
    obs.obs_property_set_modified_callback(level_p, prop_modified)
    obs.obs_property_set_modified_callback(port_p, prop_modified)
    obs.obs_property_set_modified_callback(ws_port_p, prop_modified)

    return props
def closing_scene_modified(props, properties, settings):
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "stop_streaming_delay"),
        closing_scene != "" and manage_streaming)
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "stop_recording_delay"),
        closing_scene != "" and manage_recording)
    return True
Пример #3
0
 def _add(self, p, on_changed, clear=True):
     if clear:
         self.__property = [p]
     else:
         self.__property.append(p)
     if self.doc:
         _obs.obs_property_set_long_description(p, self.doc)
     _obs.obs_property_set_visible(p, self.visible)
     _obs.obs_property_set_enabled(p, self.enabled)
     if on_changed:
         _obs.obs_property_set_modified_callback(p, on_changed)
Пример #4
0
def visible_prop(props, a, b):
    x = obs.obs_properties_get(props, a)
    obs.obs_property_set_enabled(x, b)
Пример #5
0
def show_nonvideo_participants_callback(props, p, _settings):
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, 'item_right_below'),
        not obs.obs_data_get_bool(_settings, 'show_nonvideo_participants'))
    return True
Пример #6
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
Пример #7
0
 def disable(self):
     if self.enabled:
         self.enabled = False
         for p in self.__property:
             _obs.obs_property_set_enabled(p, False)
Пример #8
0
 def enable(self):
     if not self.enabled:
         self.enabled = True
         for p in self.__property:
             _obs.obs_property_set_enabled(p, True)
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 on_property_modified(props, property, settings):
    obs.obs_property_set_enabled(obs.obs_properties_get(props, "start_scene"),
                                 manage_streaming or manage_recording)
    obs.obs_property_set_enabled(obs.obs_properties_get(props, "weekday"),
                                 (manage_streaming or manage_recording)
                                 and start_scene != "")
    obs.obs_property_set_enabled(obs.obs_properties_get(props, "event_start"),
                                 (manage_streaming or manage_recording)
                                 and start_scene != "")
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "preshow_duration"),
        (manage_streaming or manage_recording) and start_scene != "")
    obs.obs_property_set_enabled(obs.obs_properties_get(props, "text_source"),
                                 (manage_streaming or manage_recording)
                                 and start_scene != "")
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "countdown_final_text"),
        (manage_streaming or manage_recording) and text_source != ""
        and start_scene != "")

    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "closing_scene"), manage_streaming
        or manage_recording)
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "stop_streaming_delay"),
        closing_scene != "" and manage_streaming)
    obs.obs_property_set_enabled(
        obs.obs_properties_get(props, "stop_recording_delay"),
        closing_scene != "" and manage_recording)
    return True