※注:Windows VisualStudio版でしか試していません。
前提:ノートPC(FullHD:1920x1080)にサブScreen(1920x1080)を接続して使っています。
背景
WebExでATEMを使い画面共有する時にZoomみたい第2のカメラがないので何らかのビューワーが必要。(いい解決方法知っている人が居れば教えてください。)
探してもカメラボタンがあったり、Windowsの枠があったり、FullScreenにしたら引き延ばされてATEMの解像度とは異なったりして良い解決方法が見つからなかった。
そこで、枠無しのプログラムでそのままUSBカメラを表示するプログラムをOpenFrameworksで作成。
OpenFrameworksのインストール
OpenFramewroksはProcessingのC++版みたいなものです。C++なので高速です。
OpenFrameworksは無償で使えます(VisualStudio2017も、無償のCommunication Versionです)
https://openframeworks.cc/ja/download/ の
windows
ダウンロード - openFrameworks for の”visual studio (2017)”をダウンロードして
セットアップガイド - visual studio(ここにVisualStudioのダウンロードが含まれる)を見ながらインストールします 。
ソース
適当なプロジェクトを作成して、3つのファイルを変更します。
main.cppは、通常書き換えないのですが、枠無しのWindowを作成するのため変更しています。
#include "ofMain.h"
#include "ofApp.h"
//========================================================================
int main( ){
ofGLFWWindowSettings settings;
settings.setSize(CAM_WIDTH, CAM_HEIGHT);
settings.decorated = false;
shared_ptr<ofAppBaseWindow> mainwindow = ofCreateWindow(settings);
shared_ptr<ofApp> mainApp(new ofApp());
ofRunApp(mainwindow, mainApp);
ofRunMainLoop();
//ofSetupOpenGL(1024,768,OF_WINDOW); // <-------- setup the GL context
// this kicks off the running of my app
// can be OF_WINDOW or OF_FULLSCREEN
// pass in width and height too:
//ofRunApp(new ofApp());
}
ofApp.hは、上の部分でカメラ(画面)サイズを定義しています。あと下の部分に、grabber変数(カメラ)を定義しています。
#pragma once
#include "ofMain.h"
//#define CAM_WIDTH 1280
//#define CAM_HEIGHT 720
#define CAM_WIDTH 1920
#define CAM_HEIGHT 1080
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
private:
ofVideoGrabber grabber;
};
ofApp.cppは、setup関数でカメラの初期化を行っています。”Blackmagic Design”という文字列を含むカメラを探して、それを使うことにしています。KeyPressed関数の中でキーLを押すことでWindowの始点を(0,0)、Rを押すことで(1921,0)[2画面目]に移動させています。
処理が重ければSetup関数のFrameRateを変更すれば良いかなあ。。
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup() {
ofBackground(0, 0, 0);
ofSetFrameRate(30);
ofSetWindowTitle("WebEx Screen Share");
ofSetLogLevel(OF_LOG_VERBOSE);
grabber.setVerbose(true);
grabber.listDevices();
if (grabber.isInitialized() == false) {
cout << "Initalizing cam" << endl;
int index = 0;
vector<ofVideoDevice> devices = grabber.listDevices();
for (int i = 0; i < devices.size(); i++) {
ofVideoDevice& device = devices.at(i);
cout << i << ":" << device.deviceName << ":" << endl;
if (device.deviceName.find("Blackmagic Design") != std::string::npos) {
index = i;
}
}
grabber.setDeviceID(index);
grabber.initGrabber(CAM_WIDTH, CAM_HEIGHT);
cout << grabber.getWidth() << "," << grabber.getHeight() << endl;
return;
}
}
//--------------------------------------------------------------
void ofApp::update() {
grabber.update();
}
//--------------------------------------------------------------
void ofApp::draw() {
grabber.draw(0, 0);
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key) {
printf("key= %d \n", key);
int x = ofGetScreenWidth();
int y = ofGetScreenHeight();
printf("Screen Size=%d,%d \n", x, y);
if (key == 114) { //R
//ofSetWindowPosition(x - CAM_WIDTH, 0);
ofSetWindowPosition(1921, 0);
}
if (key == 108) { //L
ofSetWindowPosition(0, 0);
}
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key) {
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h) {
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg) {
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo) {
}
実行形式
FullHD(1920x1080)の画面2個ある時の想定で作っています。
配信画像は1920x1080、30fpsを想定しているものです。
”R"を押すと右画面、"L"を押すと左画面に表示されるだけの単純なものです。
”ATEM”が見つからなければ0番めのカメラの画像が表示されます。
Google Chromeはブロックされるかもです。簡単なプログラムなので、自分でコンパイルした方が良いかもしれませんね。
あと、なぜかファイルが大きいです。(Openframeworksで色々なことが出来るのを想定しているからかなあ。他の方法でも試したら良さそうですね)
https://nwws.jpn.org/files/CameraView.zip