gstreamerのサンプルコードをmacで動かしてみた(gstreamer、c、c++)
はじめに
この記事は「完全に理解したTalk Advent Calendar 2020」11日目の投稿記事です。
gstreamerを使う必要があり、頑張ってたら完全理解してしまったのでその話をします。
OSはMacOS
言語はc/c++
cmakeでビルドします。
gstreamerとは
C言語で作られたライブラリで、
動画のストリーミングほか、メディアプレイヤーの再生などに使われます。
メインの処理以外は、プラグイン、ライブラリを読み込んで処理が行われています。
Wikipediaさんより
インストール
brewでインストールします。
$ brew update #必要であれば
$ brew install gstreamer
$ brew install gst-plugins-base
$ brew install gst-plugins-good
$ brew install gstreamermm #c++でバインドしたライブラリ
必要なものはこれらです。
$ brew install gst-plugins-ugly
$ brew install gst-plugins-bad
妙な名前でざわつくものもありますが、ugly、badは飛ばして大丈夫です。
公式に説明があるようです。。
パスを通す
$ brew link gstreamer
$ brew link gst-plugins-base
$ brew link gst-plugins-good
$ brew link gstreamermm #c++でバインドしたライブラリ
$ brew link gstreamer
$ brew link gst-plugins-base
$ brew link gst-plugins-good
$ brew link gstreamermm #c++でバインドしたライブラリ
brew linkで /usr/local/lib
、/usr/local/include
にシンボリックリンクします。
cmakeを書く
gstreamerはcmakeのfindPackageは使えません。
ですが、pkg-configを使っていますのでcmakeでpkg_configを使ってリンクします。
cmake内で使われるpkg_configはパスが通っていない場合がありますので、
set(ENV{PKG_CONFIG_PATH} "/usr/local/lib/pkgconfig")
で一時的にパスを通します。
brewでインストールしリンクしたものは、/usr/local/lib/
にあります。
cmake_minimum_required(VERSION 3.15)
project(testGstreamer)
set(CMAKE_CXX_STANDARD 14)
set(ENV{PKG_CONFIG_PATH} "/usr/local/lib/pkgconfig")
find_package(PkgConfig REQUIRED)
#pkg_check_modules(GSTREAMER_LIB REQUIRED IMPORTED_TARGET gstreamer-1.0) cで使う場合はこっち
pkg_check_modules(GSTREAMERMM_LIB REQUIRED gstreamermm-1.0)
add_executable(testGstreamer main.cpp)
target_include_directories(testGstreamer PUBLIC ${GSTREAMERMM_LIB_INCLUDE_DIRS})
target_link_libraries(testGstreamer ${GSTREAMERMM_LIB_LIBRARIES})
target_compile_options(testGstreamer PUBLIC ${GSTREAMERMM_CFLAGS_OTHER})
#target_include_directories(testGstreamer PUBLIC ${GSTREAMER_LIB_INCLUDE_DIRS}) cで使う場合はこっち
#target_link_libraries(testGstreamer ${GSTREAMER_LIB_LIBRARIES}) cで使う場合はこっち
#target_compile_options(testGstreamer PUBLIC ${GSTREAMER_CFLAGS_OTHER}) cで使う場合はこっち
exampleから引っ張ってきたコード
ここのexampleをビルドしました。
#include <gstreamermm.h>
#include <glibmm/main.h>
#include <glibmm/convert.h>
#include <iostream>
#include <stdlib.h>
#include <gstreamermm/playbin.h>
namespace
{
Glib::RefPtr<Glib::MainLoop> mainloop;
// This function is used to receive asynchronous messages in the main loop.
bool on_bus_message(const Glib::RefPtr<Gst::Bus>& /* bus */,
const Glib::RefPtr<Gst::Message>& message)
{
switch(message->get_message_type()) {
case Gst::MESSAGE_EOS:
std::cout << std::endl << "End of stream" << std::endl;
mainloop->quit();
return false;
case Gst::MESSAGE_ERROR:
{
Glib::RefPtr<Gst::MessageError> msgError =
Glib::RefPtr<Gst::MessageError>::cast_static(message);
if(msgError)
{
Glib::Error err;
err = msgError->parse_error();
std::cerr << "Error: " << err.what() << std::endl;
}
else
std::cerr << "Error." << std::endl;
mainloop->quit();
return false;
}
default:
break;
}
return true;
}
} // anonymous namespace
int main(int argc, char** argv)
{
// Initialize gstreamermm:
Gst::init(argc, argv);
// Check input arguments:
if(argc < 2)
{
std::cout << "Usage: " << argv[0] << " <media file or uri>" << std::endl;
return EXIT_FAILURE;
}
// Create a playbin element.
#ifndef GSTREAMERMM_DISABLE_DEPRECATED
Glib::RefPtr<Gst::PlayBin> playbin = Gst::PlayBin::create();
#else
Glib::RefPtr<Gst::Element> playbin = Gst::ElementFactory::create_element("playbin");
#endif
if(!playbin)
{
std::cerr << "The playbin2 element could not be created." << std::endl;
return EXIT_FAILURE;
}
// Take the commandline argument and ensure that it is a uri:
Glib::ustring uri;
if(gst_uri_is_valid(argv[1]))
uri = argv[1];
else
uri = Glib::filename_to_uri(argv[1]);
// Set the playbyin2's uri property.
playbin->set_property("uri", uri);
// Create the main loop.
mainloop = Glib::MainLoop::create();
// Get the bus from the playbin, and add a bus watch to the default main
// context with the default priority:
Glib::RefPtr<Gst::Bus> bus = playbin->get_bus();
bus->add_watch(sigc::ptr_fun(&on_bus_message));
// Now set the playbin to the PLAYING state and start the main loop:
std::cout << "Setting to PLAYING." << std::endl;
playbin->set_state(Gst::STATE_PLAYING);
std::cout << "Running." << std::endl;
mainloop->run();
// Clean up nicely:
std::cout << "Returned. Setting state to NULL." << std::endl;
playbin->set_state(Gst::STATE_NULL);
return EXIT_SUCCESS;
}
実行
$ ./testGstreamer https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm
Setting to PLAYING.
Running.
End of stream
Returned. Setting state to NULL.
$ ./testGstreamer https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm
Setting to PLAYING.
Running.
End of stream
Returned. Setting state to NULL.
上のような画面が出てダウンロードしながら再生が行われます。
また、実行時、引数をローカルファイルにしても再生されますし、
mp3でも再生が行われます。
終わりに
今回は、gstreamerを使わないといけなくなったので、
まずは試しで使いました。
コマンドとしても用意されていますので、色々遊べると思います。
参考
Author And Source
この問題について(gstreamerのサンプルコードをmacで動かしてみた(gstreamer、c、c++)), 我々は、より多くの情報をここで見つけました https://qiita.com/kikochan/items/c25948b52e07e0ffc12e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .