On modern sender systems this will have ~1uS accuracy; this can be used to synchronize streams on the same connection, between connections and between machines. For inter-machine synchronization, it is important to use external clock locking capability with high precision (such as NTP).一方でSource Timing設定は、NDI SDKのtimecodeの情報をフレームの時刻として使うことになっています。 Timecodeとtimestampの違いは分かりにくいのですが、直近で送られたビデオとオーディオのtimecodeを合わせるなどのアルゴリズムが働くらしく、 OBSで使うにはtimecodeの方が適しているのではないでしょうか... なお、timecodeであっても、NTPで時刻の同期を取るべきのようです。
2020年5月4日月曜日
OBS-NDI: バージョン4.9.0がリリースされました
OBS-NDIプラグイン4.9.0がリリースされました。
4.9.0になって、Sync modesの設定値 Internal が削除されました。
もし4.8.0や以前のバージョンでInternalに設定していた場合、Source Timingに設定が変更されます。
4.8.0まではデフォルトがNetworkでしたが、4.9.0からはSource Timingがデフォルトに変更されました。
Network設定は、NDI SDKのtimestampの情報をフレームの時刻として使うのですが、異なるマシン間でのやり取りの場合は、NTPなどでシステムの時計が同期されていることが期待されているようです。以下のようにNDI SDKのドキュメントにかかれています。
2020年5月2日土曜日
OBS-Studio: GDI+とFreetype2の違い
2種類のテキストソースの違いは?
Q: OBS-Studioには、2種類のテキストソース (GDI+とFreetype2) が用意されています。 どちらを使うのが良いのでしょうか... A: WindowsではGDI+、それ以外ではFreetype2を使用しましょう。WindowsでFreetype2を使う理由はありません。 これらのプラグインは、フォントファイルの情報を元に、テキストを画像に描画し、その画像をソースとしてOBSのグラフィックスエンジンへと渡します。 GDI+とFreetype2の違いは、フォントを描画する方式の違いです。GDI+は、Windowsのコンポーネントを使うため、Windowsにしか対応していません。一方で、Freetype2は、FreeTypeというライブラリを使用します。Windowsに限らず、Mac OS XやLinuxでも動作します。GDI+の方が機能が豊富
機能を比較すると、GDI+の方が豊富です。| プラグイン | GDI+ | Freetype2 |
|---|---|---|
| ファイルから読み込み | 可能 | 可能 |
| フォント | 設定できる | 設定できる |
| 位置揃え | 左・中央・右 | 未実装、リクエストあり |
| テキストの色 | 色・透明度を設定できる | 色だけ設定できる |
| 枠 | 色・透明度・太さを設定できる | 黒・2px |
| 背景色 | 背景として矩形を塗りつぶせる | 未実装 |
ファイルの読み込み頻度
ファイルの読み込み頻度は、GDI+、Freetype2とも同じです。画像ソースも同じような実装です。 1秒間隔でファイルのタイムスタンプをポーリング、ファイルの変更を検出すると、さらに1秒後に読み込みます。ファイルを更新してから、最大で2秒の遅延が発生することになります。遅いですね。Windowsでは_wstatで1秒単位でのタイムスタンプしか取得できないので、このような実装になっているのだと思います。他のOSなら、更に速くしても問題ないはずです。
何度か (PR-1566など) リクエストは出ていますが、修正される見込みはなさそうです。
たぶん、ポーリング間隔を短くするよりは、FindFirstChangeNotificationやinotifyのような機構を使って変更を検出するような仕組みにしたいのでしょう。
もし外部のプログラムやスクリプトからテキストを更新したい場合で最大2秒の遅延が気になるのであれば、obs-websocketを使いましょう。
Python3のライブラリsimpleobswsであれば、以下のようなコードで簡単にテキストを更新できます。もしasyncioを使うのが面倒であれば、obs-websocket-pyが良いです。
import simpleobsws
ws = simpleobsws.obsws(...)
ws.call('SetSourceSettings', {'sourceName': sourceName, 'sourceSettings': {'text': text}})
その他
Freetype2でも日本語を表示することができます。もし文字化けした場合、- 日本語を表示できるフォントが設定されているか、
- ファイルからの読み込みの場合は文字コードの設定 (Linuxの場合はBOM無しのUTF-8が標準的です)
2020年4月24日金曜日
OBS websocketプラグインを使って遠隔操作する方法
OBS websocketプラグインとOBS Remote Tabletを使うと、携帯電話のブラウザなどからOBS Studioを遠隔操作できるようになります。
インストール手順を簡単に説明します。
- OBS Studioはきっと既にインストール済みでしょう...
- OBS websocketプラグインをインストールします。リリースページはこちら。
- インストールしてOBSを起動したら、メニューのTools → WebSockets Server Settingsから設定を確認します。 LANにアクセスできる人が信用できる人に限られている場合は、すなわち不特定多数がLANにアクセスできない場合には、パスワードは設定しなくても良いでしょう。
-
ファイアウォールのポートを設定します。(LAN内から接続できれば良いので、ルーターのポート解放などは不要です。)
もしFirewalldを使っているのであれば、TCPの4444番ポートを解放するのは以下のコマンドになります。sudo firewall-cmd --permanent --add-port=4444/tcp
- 携帯電話またはタブレットから、http://t2t2.github.io/obs-tablet-remote/へアクセスします。 Hostには、OBSが走っているホストのIPアドレスを入れましょう。 httpsではなくhttpでアクセスすることに注意しましょう。OBS websocketプラグインとの通信は暗号化されていませんが、ブラウザのセキュリティ設定によっては、httpsのページから暗号化されていない通信を行うことができません。
長所・短所など。
- テキストのやりとりだけなので、動作が軽快です。その代わり、映像は見えません。最近になってOBS WebSocketsにソースのスクリーンショットを送る機能が追加されたのですが、いずれシーンのサムネイルを表示できるようになるかもしれません。
- 何を表示するか、レイアウト設定から変えることができます。シーン切り替え以外に、トランジションの時間、表示中のソース、ストリーミングのステータスがあります。
- スタジオモードには対応していないようです。シーン切り替えはすぐにライブへ行きます。
使用していて、以下の問題に気づきました。
- IPv6とIPv4と両方のアドレスを持っている場合、websocketプラグインは片方のアドレスしかlistenしないようです。別のPCで使用していたときは問題なかった気がするので、デバッグが必要そうです。
-
iPhoneで使用すると、シーン切り替えでゆっくりタップすると、テキスト選択になり、シーンが切り替わらなくなることがあります。一度テキストが選択されると、同じ場所をタップしてもシーン切り替えの動作にはなりません。ページをリロードすることでテキスト選択を解除することができます。
CSSで回避できるようなので、修正提案してみるかもしれません。 - 画面上の文字や画像を選択できないようにする
2020年4月14日火曜日
iPhone+OBS Studioでライブ配信する構成
スマートフォン (iPhone) のカメラで撮影し、NDIと呼ばれるプロトコルで、パソコン上のOBS Studioを経由してライブ配信する方法を紹介します。
最近のスマートフォンには高画質なイメージセンサーが搭載されることが多く、画角が広いことを除くと、ある程度綺麗な動画を撮影することができるようになってきました。 しかしながらスマートフォンのマイクはさほど良いものではなく、配信や記録しておくにはやや劣ってしまいます。 コンサートや礼拝ではオーディオミキサーを使用するでしょうから、PC上で音声をミキサーから取り込み、スマートフォンからの映像とあわせてライブ配信へと送ることを目指します。 もし複数のスマートフォンを使用すれば、設置場所を変えて複数のシーンを切り替えながら配信することもできます。
機材の構成
使用する機材を説明します。
- iPhone - NDI HX Cameraをインストールしておきます。 以前はAndroidのアプリケーション (NewTek NDI) もあったのですが、残念なことに、今はPlay Storeで入手できません。
- PC - Mac OS X, Windows, Linuxならなんでも良いです。システム要件を確認しておきましょう。もしIntelのCPU内蔵GPUを使用しているのであれば、インテル グラフィックス・コントローラーの対応APIからOpenGLあるいはDirectXのバージョンを確認すると良いです。
また、以下のソフトをインストールします。
- OBS Studio - 配信するために使用します。
- OBS NDIプラグイン - iPhoneから届くNDIの映像をOBSへ取り込むソースプラグインです。さらにOBSからNDIで送信するプラグイン (フィルターとアウトプット) も付属していますが、今回はソースだけを使用します。
- NDIランタイムライブラリ - OBS NDIプラグインが、このランタイムライブラリを使用してNDIのパケットを受け取ります。
- 無線LANアクセスポイント - iPhoneとPCとを同一のローカルネットに接続する必要があります。少なくとも802.11nに対応していると良いでしょう。よくあるルーター・ハブ機能付の無線LANアクセスポイントを使用しましょう。私はWZR-600DHPを使用しています。
Linuxでのインストール方法
- OBSのインストール方法 - 別記事で解説しましたので、こちらをご覧ください。近日中に、Centos8へのインストール方法を記事にしようと思っています。
- OBS NDI Pluginのビルド・インストールは、他のプラグインと同じで簡単です。
git clone https://github.com/Palakis/obs-ndi.git mkdir obs-ndi/build cd obs-ndi/build cmake -DLIBOBS_INCLUDE_DIR=$PWD/../../obs-studio/libobs -DCMAKE_INSTALL_PREFIX=/usr/local .. make sudo make install - NDIランタイムライブラリのインストール - InstallNDISDK_v4_Linux.sh をダウンロードし、ファイルを展開、
libndi.so*を/usr/local/libへコピーしましょう。他のファイルは不要です。あるいは、環境変数NDI_RUNTIME_DIR_V4にライブラリへのパスを設定しても読み込んでくれるはずです。 - NDIは、Bonjourをつかって情報をやり取りするようです。Avahiを走らせ、ファイアウォールを適切に設定しておきましょう。
その他の参考情報
- Issue #448 - どうやら、音声にグリッチがのるなどの問題があるようです。iPhoneのNDI HX Camera側でオーディオをオフにしておくのがワークアラウンドになるようです。
- ゲーム実況で使うPCについて理解しよう - もしPCを購入するのであれば、参考になる情報だと思います。要は、高性能なCPUが望ましいですが、メモリーはさほどコストをかけなくて良いということです。
2020年3月21日土曜日
OBS-Studioでテキストに白い輪郭をつける方法 (freetype2)
OBS-Studioのテキストプラグイン (freetype2) では、設定により黒色の輪郭 (アウトライン) や影をつけることができます。
明るい背景に文字を出す場合、黒の文字に、白の輪郭をつけたくなるのですが、残念ながら、輪郭の色はソースコード中でハードコードされていおり、変更することはできません。
なお、Freetype2とGDI+との違いについて、こちらのページにまとめました。
テキストプラグインでは設定できないのですが、後処理としてLUTエフェクトを使用することで、輪郭の色を変更することができます。
この方法を紹介します。
- 白黒を反転させるLUTを用意します。
下のPNGを使用できます。2種類用意しましたが、1個目はただ色を反転するだけ、2個目は明るさだけ反転し色相はそのままにしています。ファイルが圧縮されてしまっています。非圧縮のPNGを生成することをおすすめします。 - まず、白の文字で黒の輪郭付のテキストを作ります。
- LUTエフェクトを追加し、白黒を反転させるLUTを適用します。
2020年3月20日金曜日
OBS Studio テキストプラグインのファイルポーリング間隔の変更
OBS Studioでローカルファイルを読み込むようにすると、1秒間隔でしかファイルの更新がチェックされません。
これでは遅延が気になるので、変更する方法を探しました...
残念ながら設定項目はないので、ソースコードを変更することになります。
以下のように0.1秒毎にファイルのタイムスタンプをチェックするよう書き換えます。変更自体は簡単なのですが、ビルドしなおすのは面倒です。
diff --git a/plugins/obs-text/gdiplus/obs-text.cpp b/plugins/obs-text/gdiplus/obs-text.cpp
index c452821..9b8c804 100644
--- a/plugins/obs-text/gdiplus/obs-text.cpp
+++ b/plugins/obs-text/gdiplus/obs-text.cpp
@@ -803,11 +803,11 @@ inline void TextSource::Tick(float seconds)
update_time_elapsed += seconds;
- if (update_time_elapsed >= 1.0f) {
+ if (update_time_elapsed >= 0.1f) {
time_t t = get_modified_timestamp(file.c_str());
update_time_elapsed = 0.0f;
if (update_file) {
LoadFileText();
TransformText();
RenderText();
diff --git a/plugins/text-freetype2/text-freetype2.c b/plugins/text-freetype2/text-freetype2.c
index bc2dd18..a63621f 100644
--- a/plugins/text-freetype2/text-freetype2.c
+++ b/plugins/text-freetype2/text-freetype2.c
@@ -244,11 +244,11 @@ static void ft2_video_tick(void *data, float seconds)
if (!srcdata->from_file || !srcdata->text_file)
return;
- if (os_gettime_ns() - srcdata->last_checked >= 1000000000) {
+ if (os_gettime_ns() - srcdata->last_checked >= 100000000) {
time_t t = get_modified_timestamp(srcdata->text_file);
srcdata->last_checked = os_gettime_ns();
if (srcdata->update_file) {
if (srcdata->log_mode)
read_from_end(srcdata, srcdata->text_file);
else
2箇所変更したのですが、どうやらLinuxではtext-freetype2の方を変更すれば良かったようです。
obs-text/gdiplusは、名前からしてWindows用なのでしょう。
2020年3月19日木曜日
OpenLPのテキストをOBS Studioへ送る方法
はじめに
このサイトのメインテーマからは外れるのですが、歌詞をプロジェクタで映すのに我々はOpenLPというソフトを使用しています。 この記事では、OpenLPのテキストをOBS Studioへオーバーレイする方法を紹介します。 OpenLPには遠隔操作のプラグインが組み込まれていて、JSONをHTTP経由でやり取りするプロトコルになっています。一方で、OBS Studioにはローカルに置かれたテキストファイルを読み込み、オーバーレイして表示する機能がついています。 この間に入って、OpenLPからテキストを取り出しローカルファイルに保存すれば、OpenLPのテキストをOBS Studioへ送ることが簡単にできます。OpenLPの設定
遠隔操作プラグインを有効にしましょう。 もしOpenLPとOBS Studioが別のホスト上で動いている場合、OpenLPが動作しているホストのIPアドレスを固定しておくべきです。 さらに、ファイアウォールの4316番ポートを開けておく必要があります。スクリプト
OpenLPとOBS Studioの間に入るスクリプトは、Pythonで書きます。 たったの160行です。
#! /bin/env python
# -*- coding: utf-8 -*-
import re
url_base = 'http://127.0.0.1:4316'
url_text = url_base + '/api/controller/live/text'
url_poll = url_base + '/api/poll'
fname_out = '/dev/shm/olp.txt'
fname_tmp = fname_out+'~'
n_maxchar = 50
flg_print = False
r_ascii = re.compile('[0-9a-zA-Z: ()]')
def my_count(s):
ret = 0
for c in s:
ret += 1 if r_ascii.match(c) else 2
return ret
def get_olp_text():
import urllib
import json
data = urllib.urlopen(url_text).read()
#print data
j = json.loads(data)
if flg_print: print j
for x in j['results']['slides']:
if 'img' in x:
return ''
if x['selected']:
return x['text']
return ''# return j['results']['slides'][0]['text']
def olp_poll():
import urllib
import json
j = json.loads(urllib.urlopen(url_poll).read())
if flg_print: print j
is_blank = j['results']['blank']
is_theme = j['results']['theme']
is_display = j['results']['display']
if is_blank or is_theme or is_display:
return False
return j
j_poll_prev = None
def get_olp():
global j_poll_prev
while True:
j = olp_poll()
if j != j_poll_prev:
j_poll_prev = j
break
from time import sleep
sleep(0.1)
if j:
return get_olp_text()
else:
return ''
def obs_output(data):
import codecs
with codecs.getwriter('utf8')(open(fname_tmp, 'w')) as f_tmp:
f_tmp.write(data)
import os
os.rename(fname_tmp, fname_out)
_r_nowrap = re.compile(u'[。、」]')
_r_alnum = re.compile(u'[A-Za-z0-9,.]')
_r_wrap = re.compile(u'[「]$')
def my_split(data, n_th):
data = re.sub(u"[ \t ]+", ' ', data)
line = u''
lines = []
n_line = 0
c_prev = ''
for c in data:
n = my_count(c)
if \
n_line + n <= n_th or \
_r_nowrap.match(c) or \
(_r_alnum.match(c) and _r_alnum.match(c_prev)) :
line += c; n_line += n
else:
t = _r_wrap.search(line)
if t:
t = t.start()
lines.append(line[0:t])
line = line[t:] + c
n_line = my_count(c)
else:
lines.append(line)
line = c; n_line = n
c_prev = c
if len(line):
lines.append(line)
return lines
def split_long_line(v, n):
v1 = []
for s in v:
v2 = my_split(s, n)
for t in v2:
v1.append(t)
return v1
def myfilter(s):
import re
s = re.sub(u'\([^()]*\)', '', s)
s = re.sub(u'!', '! ', s)
s = re.sub(u"[ ]\+", ' ', s)
s = re.sub(u' $', '', s)
s = re.sub(u'1', '1', s)
s = re.sub(u'2', '2', s)
s = re.sub(u'3', '3', s)
s = re.sub(u'4', '4', s)
s = re.sub(u'5', '5', s)
s = re.sub(u'6', '6', s)
s = re.sub(u'7', '7', s)
s = re.sub(u'8', '8', s)
s = re.sub(u'9', '9', s)
s = re.sub(u' *×[1-9]', '', s) # 繰り返しを「x2」と書くことがあるけれど、消してしまう。
n = n_maxchar
v = s.split('\n')
v = split_long_line(v, n)
i=0; s=''
for s1 in v:
i1 = my_count(s1)
if i + i1<n:
s = s+' ' + s1 if len(s) else s1
i += i1 + 1
else:
s += '\n' + s1 if len(s) else s1
i = i1
return s
def main():
s_prev = ''
while True:
try:
s_org = get_olp()
if s_org != s_prev:
s_prev = s_org
s = myfilter(s_org)
if flg_print: print u'display: %s'%s
obs_output(s)
from time import sleep
sleep(1)
except:
# OpenLPが起動していない場合など
obs_output(u'')
from time import sleep
sleep(10)
if __name__=='__main__':
main()
get_olpで、OpenLPからテキストを取得してきます。
OpenLPが別ホストで走っている場合は、url_baseとを書き換えましょう。
0.1秒毎に変更がないかポーリングし、変更があった場合はテキストを取得します。
ブランクかどうかの情報も取得し、ブランクならば空文字 ('') を返します。
myfilterで表記ゆらぎを修正し、改行を整えます。改行する文字数は、n_maxcharで設定できます。
行頭に句読点を入れないなど、禁則処理も行います。
英語の場合は、文字によって文字幅が異なるので、OBS Studioに改行処理をやらせたほうが良いでしょう。
最後に、obs_outputでファイルへ書き出します。
必要に応じて、出力先fname_outを書き換えましょう。
どのタイミングでファイルが読み込まれても良いように、一時ファイル fname_tmp へ書き出した後、renameを使ってファイルを置き換えます。
LinuxやMac OS Xではこの操作のアトミック性が保証されており、OBS Studioは書き換え途中のファイルを開くことはなく、書き換え前・書き換え後いずれかを開くはずです。
OBS Studioの設定
シーンにテキストを追加し、以下のようにファイルからの読み取りにします。課題
OBS Studioでは、ファイルのタイムスタンプを1秒毎にチェックし、更新があれば読み出すようになっています。 テキストファイルを介するのでなくwebsocketを使ってテキストを送るスクリプトを作成しました。いずれ公開するかもしれません。2020年3月18日水曜日
SL7にOBS Studioをインストール
はじめに
Scientific Linux 7にOBS Studioをビルドしてインストールしたときのメモ。 普通はWindowsやMac OS Xを選ぶと思いますので、このページにたどり着いた読者はLinuxのインストールくらいは慣れているものとして執筆することにします。なぜScientific Linux
他のOSやLinuxディストリビューションと比べて、サポート期間が長く、古いバージョンで固められていて安定していると考えられるため、Scientific Linux 7を選びました。 当時はまだCentOS 8が出ていな方ので、7が最新メジャーバージョンでした。RPMでインストールするソフトウェア
OSは既にインストールできているものとして、以下のパッケージを追加でインストールします。ソースからビルドするソフトウェア
1. FFmpeg
動画のエンコード・デコードツールの定番です。$ git clone https://git.ffmpeg.org/ffmpeg.git $ cd ffmpeg $ mkdir b $ cd b $ ../configure --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --arch=x86_64 --enable-libmp3lame --enable-pic --enable-libfreetype --enable-shared --enable-libxcb --disable-libmfx --disable-nvenc --enable-libpulse $ make -j8 $ sudo make install
2. x264
GITレポジトリhttp://git.videolan.org/git/x264.git からクローンして、ビルド・インストールしました。
3. OBS-Studio
$ git clone https://github.com/jp9000/obs-studio.git $ cd obs-studio $ b=b-$(date +%Y%m%d) $ mkdir $b && cd $b && cmake -DUNIX_STRUCTURE=1 .. $ make -j8 $ sudo make install
3.1. OBS-websocket
OBS Studioをインストールした後、OBS-websocketをビルド・インストールします。 OBS Studioのライブラリを読み込むので、OBS Studioをアップデートした後は忘れずビルドし直さなければなりません。$ cd ../.. $ git clone https://github.com/Palakis/obs-websocket.git $ cd obs-websocket $ mkdir $b && cd $b $ cmake -DLIBOBS_INCLUDE_DIR=../obs-studio/libobs -DCMAKE_INSTALL_PREFIX=/usr/local .. $ make $ /usr/lib64/qt5/bin/uic -o ui_settings-dialog.h ../src/forms/settings-dialog.ui $ makeQTのバージョンのためか、CMakeがつくるMakefileの中で
uicが流れていなかったので、手動でuicを実行し、再度makeを流しました。
設定
AlsaとPulseAudioの設定
PulseAudioの設定で、サンプリングレートを48kHzに固定します。 設定ファイル/etc/pulse/daemon.conf に以下の設定を追加します。
default-sample-rate = 48000このとき、代替サンプリングレート
alternate-sample-rate を設定してはいけません。
例えば代替サンプリングレートを44.1kHzに設定していると、他のソフトを起動した際に44.1kHzに変更されてしまうことがあり、録音・配信途中で音声がずれてしまいます。
グループ設定
OBS Studioを使用するユーザに、グループvideo audio を割り当てておきます。
videoはV4L2のデバイスにアクセスするために必要、audioはもしかすると不要かも。
BlackMagicのキャプチャカードを使用するのであれば、videoは不要です。
OBS Studioの起動
以下のスクリプトを用意しておき、このスクリプトでOBS Studioを起動します。#! /bin/bash export LANG=ja_JP.UTF-8 export LD_LIBRARY_PATH=/usr/local/lib: export QT_IM_MODULE=ibus export XMODIFIERS=@im=ibus export GTK_IM_MODULE=ibus exec /usr/local/bin/obs
登録:
投稿 (Atom)
色彩の印象について
このページに、PCCSトーンとその印象についてわかりやすく書かれていて参考になった。こんど映像を編集する機会があれば、このページを参考にしたいと思う。 著者は大学で映像制作を学んだ方のようで、基礎をわかりやすく説明されているように感じる。他の記事も読みたい。 【映像制作者が...
-
2種類のテキストソースの違いは? Q: OBS-Studioには、2種類のテキストソース (GDI+とFreetype2) が用意されています。 どちらを使うのが良いのでしょうか... A: WindowsではGDI+、それ以外ではFreetype2を使用しましょう。Wind...
-
OBS websocket プラグインと OBS Remote Tablet を使うと、携帯電話のブラウザなどからOBS Studioを遠隔操作できるようになります。 使用するツールとその接続は以下の図のようになります。 インストール手順を簡単に説明...
-
OBS-Studioのテキストプラグイン (freetype2) では、設定により黒色の輪郭 (アウトライン) や影をつけることができます。 明るい背景に文字を出す場合、黒の文字に、白の輪郭をつけたくなるのですが、残念ながら、輪郭の色はソースコード中でハードコードされていおり、変...








