LoginSignup
1
1

More than 3 years have passed since last update.

【その2】ZOOM, Teamsなどのためのサブタイトル(字幕)表示ツール【受信・表示プログラム】

Last updated at Posted at 2021-02-15

【その2】ZOOM, Teamsなどのためのサブタイトル(字幕)表示ツール【受信・表示部】

受信・表示プログラム

 前回 https://qiita.com/quittardis/items/317df7b23a64e82bf6a2 
 の続きです。
 前回の送信プログラムでudp経由で送られてきた全角漢字をカメラ画像にスーパー
インポーズして字幕として表示します。さらにこの画像をSpoutで仮想カメラ化して
ZOOMやTeamsで使えるようにします。

ソースコードのbugfix版はhttps://github.com/ultrahamlet/SjFX のsrcフォルダに置きました。

スクリーンショット 2021-02-15 115548.jpg

(buildが苦手という方は、このhttps://github.com/ultrahamlet/SjFX
gitにあるbinaryファイルで実験できる。
SjFX.exeが受信・表示プログラム。WindowsProject.exeが文字送信プログラム。
実験時にWebCamの接続とSpoutCamのインストールも忘れずに)
 
 先ず、SpoutSDK https://spout.zeal.co/
をopenframeworksのプロジェクトフォルダと同じ階層に置きます。

openframeworksのアドオンは、

ofxNetworks
ofxXmlSettings

を追加します。

ofApp.hでinlcludeに以下の四行を追加します。

#include "ofxXmlSettings.h"
#include "..\..\SpoutSDK\SpoutSender.h"
#include <Windows.h>
#include "ofxNetwork.h"

ofApp.h

ofApp.hでinlcludeに以下のように変数を追加します。

        ofVideoGrabber grabber;
        //
        char sendername[256];     // Sender name
        SpoutSender sender;    // Spout sender object
        unsigned int senderwidth;  // Dimensions of the sender can be independent
        unsigned int senderheight; // of the application window if using an fbo
        ofFbo  oFbo;
        ofFbo spFbo;           // For texture send example
        // udp FONT
        ofxUDPManager udpConnectionRx;
        ofxUDPManager udpConnectionTx;

        string rxMessage;
        string txMessage;
        string recvStr;
        string ostr;
        BOOL received;
        ofTrueTypeFont font;

ofApp.cppの#include "ofApp.h"以下の行を追加します。
主に漢字コードを変換する関数です。

#include <codecvt>
//--------------------------------------------------------------
std::wstring multi_to_wide_capi(std::string const& src)
{
    std::size_t converted{};
    std::vector<wchar_t> dest(src.size(), L'\0');
    if (::_mbstowcs_s_l(&converted, dest.data(), dest.size(), src.data(), _TRUNCATE, ::_create_locale(LC_ALL, "jpn")) != 0) {
        throw std::system_error{ errno, std::system_category() };
    }
    dest.resize(std::char_traits<wchar_t>::length(dest.data()));
    dest.shrink_to_fit();
    return std::wstring(dest.begin(), dest.end());
}
std::string wide_to_utf8_cppapi(std::wstring const& src)
{
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.to_bytes(src);
}

std::string multi_to_utf8_cppapi(std::string const& src)
{
    auto const wide = multi_to_wide_capi(src);
    return wide_to_utf8_cppapi(wide);
}

std::string toUtf8(const std::wstring &str)
{
    std::string ret;
    int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0, NULL, NULL);
    if (len > 0)
    {
        ret.resize(len);
        WideCharToMultiByte(CP_UTF8, 0, str.c_str(), str.length(), &ret[0], len, NULL, NULL);
    }
    return ret;
}

ofApp::setup()

void ofApp::setup()に以下の行を追加します。
フォントの読み込みと、
udpの接続の設定です。
フォントはdataフォルダの下のFotnsにWindows/Fontsからコピーしておきます。

grabber.setup(ofGetWidth(), ofGetHeight());

    senderwidth = ofGetWidth();
    senderheight = ofGetHeight();
    // Create an RGBA fbo for texture transfers
    spFbo.allocate(senderwidth, senderheight, GL_RGBA);
    oFbo.allocate(ofGetWidth(), ofGetHeight(), GL_RGBA);
    //oFbo.getTextureReference().getTextureData().bFlipTexture = true;

    // If no name is specified, the executable name is used.
    sender.SetSenderName(sendername);
    // Update caption in case of multiples of the same sender
    ofSetWindowTitle(sender.GetName());
    //
    // Font setting
    ofTrueTypeFontSettings fsettings("Fonts/meiryo.ttc", 24);
    fsettings.addRanges(ofAlphabet::Emoji);//絵文字
    fsettings.addRanges(ofAlphabet::Japanese);//日本語
    fsettings.addRange(ofUnicode::Space);//スペース
    fsettings.addRange(ofUnicode::IdeographicSpace);//全角スペース
    fsettings.addRange(ofUnicode::Latin);//アルファベット等
    fsettings.addRange(ofUnicode::Latin1Supplement);//記号、アクサン付き文字など
    fsettings.addRange(ofUnicode::NumberForms);//数字?
    fsettings.addRange(ofUnicode::Arrows);//矢印
    fsettings.addRange(ofUnicode::MathOperators);//数式記号
    fsettings.addRange(ofUnicode::Hiragana);//ひらがな
    fsettings.addRange(ofUnicode::Katakana);//カタカナ
    fsettings.addRange(ofUnicode::MiscSymbolsAndPictographs);//絵文字など
    fsettings.addRange(ofUnicode::Emoticons);//エモーティコン
    //settings.addRange(ofUnicode::KatakanaHalfAndFullwidthForms);//エモーティコン
    //
    if (!font.load(fsettings))
        cout << "couldn't load font" << endl;
    //
    // udp connect
    udpConnectionRx.Create();
    udpConnectionRx.Bind(12345); //incomming data on my port # ...  
    udpConnectionRx.SetNonBlocking(true);

    received = false;

ofApp::update()

void ofApp::update()を以下のリストを追加します。
udpデータを待ち受け受信します。
受信したデータは、recvStrにストアします。


grabber.update();

    // UDP 受信
    char data[512];
    //unsigned short int *val;
    udpConnectionRx.Receive(data, 512);
    //std::cout << str << "-" <<  std::endl;
    uint16_t *val = (uint16_t*)data;
    //std::cout << val[0] << std::endl;
    BOOL strOK = true;
    for (int i = 0; i < sizeof(val); i++) {
        if (val[i] < 256) { strOK = false; break; }
    }
    if (strOK) {
        recvStr = data;
        received = true;
        std::cout << recvStr << std::endl;
        // shift-jis -> utf8
        ostr = multi_to_utf8_cppapi(recvStr);
        std::cout <<  "Received" << std::endl;
    }

ofApp::draw()

void ofApp::draw()に以下のリストを追加します。

受信したデータを表示し、Spoutで仮想カメラに送信します。
ソースコードのbugfix版はhttps://github.com/ultrahamlet/SjFX のsrcフォルダに置きました。以下のコードは、2月16日以降修正しています。それ以前のコードでは、SpoutCamに文字が出力されません。

    oFbo.begin();

     ofSetColor(255, 255, 255);

     grabber.draw(0, 0);
    // font.drawString(u8"漢字テスト", 0, 200);
     if (received) font.drawString(ostr, 200, ofGetHeight()-30);
    oFbo.end();

    spFbo.begin();    
    //grabber.draw(0, 0);
    if (flipY) {
        ofScale(-1, 1);
        ofTranslate(-ofGetWidth(), 0);
    }
    oFbo.draw(0, 0);
     sender.SendFbo(oFbo.getId(), senderwidth, senderheight, false);
    spFbo.end();

    oFbo.draw(0, 0);

SpoutCamのインストール

最後にSpoutCam-2.023をインストールします。
 SpoutCam-2.023\release\x64下の
 _register_run_as_admin.bat
 (zoom用に32bit版もインストールする。)
を、管理者として実行します。
これで、ZOOM、TeamsなどからカメラとしてSpoutを選択します。

あっ忘れてました。

 dataフォルダ化に以下の内容のsttings.htmlを置いてください。
ここにはカメラに最適の縦横の値を書いておきます。

<settings>
    <app>
        <width>960</width>
        <height>544</height>
    </app>
</settings>

 
gitのbinの中のMySetting.exeでも設定できる。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1