WebSockets API for OBS Studio. or Remote-control of OBS Studio through WebSocket
'os': 'Ubuntu 20.04.3 LTS (Focal Fossa)',
'python': 'Python 3.8.10',
'obs-studio-version': '27.1.3',
// obs-websocket: https://github.com/obsproject/obs-websocket/tree/4.x-current
'obs-websocket-version': '4.9.1',
// simpleobsws: https://github.com/IRLToolkit/simpleobsws/tree/simpleobsws-4.x
'simpleobsws': '1.2.1'
OBS Studio
我的系统是ubuntu 20.04 lts,安装过程可以参考官方文档,比较简单,目前obs还不支持arm架构的.
https://github.com/obsproject/obs-studio/wiki/install-instructions#ubuntumint-installation
sudo apt install ffmpeg
# 虚拟摄像头
sudo apt install v4l2loopback-dkms
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt update
sudo apt install obs-studio
obs-websocket and simpleobsws
现在主分之是5.x版本,我用的是4.x版本,注意区别.
https://github.com/obsproject/obs-websocket/tree/4.x-current https://github.com/IRLToolkit/simpleobsws/tree/simpleobsws-4.x
# install obs-websocket
wget https://github.com/obsproject/obs-websocket/releases/download/4.9.1/obs-websocket_4.9.1-1_amd64.deb
dkpg -i obs-websocket_4.9.1-1_amd64.deb
# install sampleobs
pip3 install simpleobsws
安装完obs-websocket之后,记得重启obs,之后点击"工具" --> "websocket服务器",然后配置obs-websocket.

WebSocket 服务器设置
记得设置密码,还有防火墙是否开启外部网络访问,我的是本地调用,故添加ufw禁止22333端口的访问
#禁止
ufw deny 22333
#允许
ufw allow 22333
# 删除规则
ufw delete deny 22333
# or
ufw ufw allow 22333 api调用我使用的是sample_request方式,request方式.
https://github.com/IRLToolkit/simpleobsws/blob/simpleobsws-4.x/samples/sample_request.py
import asyncio
import simpleobsws
loop = asyncio.get_event_loop()
ws = simpleobsws.obsws(host='127.0.0.1', port=22333, password='Fungit.org', loop=loop)
async def make_request():
await ws.connect() #
result = await ws.call('GetVersion')
print(result)
await ws.disconnect()
loop.run_until_complete(make_request()) 执行之后,大概会返回这样的json数据
{'available-requests': 'AddFilterToSource,AddSceneItem,Authenticate,BroadcastCustomMessage,CreateScene,CreateSource,DeleteSceneItem,DisableStudioMode,DuplicateSceneItem,EnableStudioMode,ExecuteBatch,GetAudioActive,GetAudioMonitorType,GetAudioTracks,GetAuthRequired,GetBrowserSourceProperties,GetCurrentProfile,GetCurrentScene,GetCurrentSceneCollection,GetCurrentTransition,GetFilenameFormatting,GetMediaDuration,GetMediaSourcesList,GetMediaState,GetMediaTime,GetMute,GetOutputInfo,GetPreviewScene,GetRecordingFolder,GetRecordingStatus,GetReplayBufferStatus,GetSceneItemList,GetSceneItemProperties,GetSceneList,GetSceneTransitionOverride,GetSourceActive,GetSourceDefaultSettings,GetSourceFilterInfo,GetSourceFilters,GetSourceSettings,GetSourcesList,GetSourceTypesList,GetSpecialSources,GetStats,GetStreamingStatus,GetStreamSettings,GetStudioModeStatus,GetSyncOffset,GetTextFreetype2Properties,GetTextGDIPlusProperties,GetTransitionDuration,GetTransitionList,GetTransitionPosition,GetTransitionSettings,GetVersion,GetVideoInfo,GetVirtualCamStatus,GetVolume,ListOutputs,ListProfiles,ListSceneCollections,MoveSourceFilter,NextMedia,OpenProjector,PauseRecording,PlayPauseMedia,PreviousMedia,RefreshBrowserSource,ReleaseTBar,RemoveFilterFromSource,RemoveSceneTransitionOverride,ReorderSceneItems,ReorderSourceFilter,ResetSceneItem,RestartMedia,ResumeRecording,SaveReplayBuffer,SaveStreamSettings,ScrubMedia,SendCaptions,SetAudioMonitorType,SetAudioTracks,SetBrowserSourceProperties,SetCurrentProfile,SetCurrentScene,SetCurrentSceneCollection,SetCurrentTransition,SetFilenameFormatting,SetHeartbeat,SetMediaTime,SetMute,SetPreviewScene,SetRecordingFolder,SetSceneItemCrop,SetSceneItemPosition,SetSceneItemProperties,SetSceneItemRender,SetSceneItemTransform,SetSceneTransitionOverride,SetSourceFilterSettings,SetSourceFilterVisibility,SetSourceName,SetSourceRender,SetSourceSettings,SetStreamSettings,SetSyncOffset,SetTBarPosition,SetTextFreetype2Properties,SetTextGDIPlusProperties,SetTransitionDuration,SetTransitionSettings,SetVolume,Sleep,StartOutput,StartRecording,StartReplayBuffer,StartStopRecording,StartStopReplayBuffer,StartStopStreaming,StartStopVirtualCam,StartStreaming,StartVirtualCam,StopMedia,StopOutput,StopRecording,StopReplayBuffer,StopStreaming,StopVirtualCam,TakeSourceScreenshot,ToggleMute,ToggleStudioMode,TransitionToProgram,TriggerHotkeyByName,TriggerHotkeyBySequence', 'obs-studio-version': '27.1.3', 'obs-websocket-version': '4.9.1', 'status': 'ok', 'supported-image-export-formats': 'bmp,cur,icns,ico,jpeg,jpg,pbm,pgm,png,ppm,tif,tiff,wbmp,webp,xbm,xpm', 'version': 1.1} 这串数据可以看出当前可用的请求available-requests,和版本信息等'obs-studio-version': '27.1.3', 'obs-websocket-version': '4.9.1'.
最后的最后,还是看obs-websocket的api文档,注意是Request.
https://github.com/obsproject/obs-websocket/blob/4.x-current/docs/generated/protocol.md#requests
直播间目前弹幕控制obs的代码,有空再聊弹幕姬那部分了.
ps: 由于我的直播视频是通过streamlink打开的,所以需要shell\screen,如果是捕获浏览器窗口可忽略call shell部分
async def obs_ws_action(self, actions, name):
try:
ws = simpleobsws.obsws(host='127.0.0.1', port=22333, password='Fungit.org')
print("action is :" + name)
await ws.connect()
# 切换直播和视频
if actions == "ChangeMain" or actions == "ChangeVideo":
print("切换直播")
data_1 = {'sourceName': 'Activity'}
data_2 = {'sourceName': 'MainVideo'}
if actions == "ChangeMain":
# call shell
data_1 = {'sourceName': 'MainVideo'}
data_2 = {'sourceName': 'Activity'}
result = await ws.call('RestartMedia', data_1)
await asyncio.sleep(1)
result = await ws.call('StopMedia', data_2)
print(result)
if actions == "OpenVICI" or actions == "CloseVICI":
print("打开关闭副镜头")
data_1 = {'sourceName': 'VICI'}
if actions == "OpenVICI":
# call shell
result = await ws.call('RestartMedia', data_1)
return
result = await ws.call('StopMedia', data_1)
print(result)
elif actions == "RestartMedia" :
MainVideo = {'sourceName': 'MainVideo'}
result = await ws.call('RestartMedia', MainVideo)
print(result)
elif actions == "RestartStreaming":
print("重启推流")
result = await ws.call('StopStreaming')
await asyncio.sleep(3)
data = {}
result = await ws.call('StartStreaming', data)
print(result)
else:
print("nothing")
print(result)
await ws.disconnect()
except Exception as e:
print(e)
await ws.disconnect()
pass
所以直播间的obs控制弹幕为(需要权限):
弹幕关键字重启、刷新主镜头,注意是以@开头; 刷新流和主镜头:@RestartMedia、@RestartMain、@重启
切换镜头:两个画面,一个是直播的镜头,一个是录像视频; 直播画面:@切换主镜头、@切换直播、@ChangeMain ; 录像画面:@切换录像、@切换视频、@ChangeActivity
显示/隐藏副镜头; 显示副镜头:@显示副镜头、@打开副镜头、@OpenVICI; 隐藏副镜头:@隐藏副镜头、@关闭副镜头、@CloseVICI
最后讲下手机怎么加入应援团:
因为玩B站比较晚,甚至不知道应援团还有二维码的存在,无意中看到一张应援团的二维码,通过扫码之后得到一个链接
网页链接;params=eyJpZCI6MjIxMDgxOTc5LCJ0eXBlIjoxfQ==
虽然不知道params那个部分是什么,但是熟悉编码的都有印象,拿去base64解码之后,得到的是
https://www.base64decode.org/
{"id":221081979,"type":1} 得到的json数据很容易看出来,id就是应援团的id,type暂时不知道作用,默认就好了,所以你想生成自己的应援团链接,把上面id改为你的应援团id,然后拿去encode,替换params=“应援团base64”
https://www.base64encode.org/
我的手机应援团入口:网页链接;params=eyJpZCI6MjIxMDgxOTc5LCJ0eXBlIjoxfQ==