OBS Studio在Qt Creator的编译步骤


  • 网站研运

    我们的萌梦项目想与obs-studio整合一下,借助它的推流功能实现我们的目标,于是我开始研究如何顺利地构建obs-studio了。

    久仰大名

    2016年年初,我们就借助直播这一阵风给我们论坛添加上直播这个很棒的功能了,当时我们选择的直播平台使用的直播软件是OBS。当时的OBS还是用MFC制作的,所以开始还是比较笨拙的,后面OBS的作者采用了Qt制作新的版本obs-studio,这样和我们开发使用的技术是相通的了。那是我最早了解到OBS软件。

    努力制作

    后面由于我们全力制作我们的动作编辑器,和OBS的研发路子岔开了。转眼就到了2018年了,我们的动作编辑器更新了一个又一个版本,而OBS这款软件也经过了多个更新,现在已经变成非常成熟的直播软件了。我们随便在百度可以看到,现在很多主播都在使用OBS进行直播活动。虽然直播在中国的已经慢慢的消退了,但是直播技术作为一种越来越稳定的技术被沉淀下来。于是我们在想能否利用直播这个新鲜事物来为我们的动作编辑器添加一些特色呢?于是有了这次OBS Studio在Qt Creator上的编译步骤。

    准备工作

    为了编译OBS Studio我们的准备工作是要做的。一个基本的认识是OBS Studio是用的是Qt进行编译的,并且OBS Studio是跨平台的,于是我们要将最新的Qt版本安装好。接着呢由于大多数网上的教程都介绍到OBS Studio使用MSVC进行构建的,于是我们尝试使用MSVC 2015来构建它。

    OBS Studio在官网上放出了源代码,源代码是挂在github上的,于是我们从github上下载最新的源代码,以便了解OBS Studio是如何工作的。使用git克隆OBS Studio:

    git clone --recursive https://github.com/jp9000/obs-studio
    

    由于OBS依赖FFMPEG等库,因此官网吧这些库编译了一遍并且放在了一起了。因此我们还需要下载这些库:

    https://obsproject.com/downloads/dependencies2015.zip
    

    我们下载的是VS2015编译的库。
    下载好了之后放在一个目录下。我这边的目录是:G:\QtProject\obs-studio-dependencies\win32

    Qt Creator十分方便,我们可以直接打开Qt Creator进行构建。这和官网上介绍的稍微有些不同,这里记录一下。
    由于CMake在configure的时候要指定一些变量,因此按照下图的方式进行配置:
    0_1515592451271_保存的图.png

    接着也不使用小锤子进行构建了,直接点击三角形进行运行,会顺带构建的,稍等十五分钟吧。
    0_1515592776638_1111131.png

    构建好了之后,我们在类似下面的路径中可以找到obs32.exe。

    G:\QtProject\build-obs-studio-Desktop_Qt_5_10_0_MSVC2015_32bit-Minimum Size Release\rundir\MinSizeRel\bin\32bit
    

    当然双击运行的时候会缺少Qt库。最后只需要将三个Qt库复制粘贴一下就好了。

    Qt5Core.dll Qt5Gui.dll Qt5Widgets.dll

    好了,OBS可以运行啦。
    0_1515593896117_fedc7416-0612-4f14-bccc-bd0849f9cfb7-image.png

    结语

    经过了两到三年的发展OBS Studio已经成为直播业界最有名的跨平台的开源软件了。而我们也想利用OBS Studio在这方面成功之处为我们的动作编辑器添加直播推流的功能,这样的话可玩性就会更高。我们也期待以后能够出现更有意思的玩法。



  • 没想到编译一个大型软件也会这么容易啊!!话说,可以用mingw或者VS2013编译吗?另外你说的“最新的Qt版本”到底是哪个版本啊?



  • @stlcours 可以的,MinGW暂时不行,可能要自己魔改,但是VS2013是作者使用的版本,可以直接用。



  • 您好,我搞这个搞一天了。。一些细节步骤在文章里没有看到
    是这样的:
    我在github上clone项目到本地,然后用QT creator打开 项目中的CMakeList.txt,然后就开始构建,但运行的时候就出错: 14:37:27: 为项目obs-studio执行步骤 ...
    14:37:27: 正在启动 "C:\Program Files\CMake\bin\cmake.exe" --build . --target all

    Microsoft(R) 生成引擎版本 12.0.40629.0
    [Microsoft .NET Framework 版本 4.0.30319.42000]
    版权所有 (C) Microsoft Corporation。保留所有权利。

    MSBUILD : error MSB1009: 项目文件不存在。
    开关: all.vcxproj
    14:37:28: 进程"C:\Program Files\CMake\bin\cmake.exe"退出,退出代码 1 。
    Error while building/deploying project obs-studio (kit: Qt 5.8.0 (msvc2013))
    The kit Qt 5.8.0 (msvc2013) has configuration issues which might be the root cause for this problem.
    When executing step "CMake Build"
    14:37:28: Elapsed time: 00:00.
    急,在线等。。



  • @tobin 嗯,我稍微看一下哈。然后我来回复一下你。



  • @tobin 有几个问题想向你确认一下:
    1、有安装obs的依赖项吗?下载地址:这里
    2、有按照下图的方式对Qt Creator中obs项目的构建进行设置吗?
    图片地址



  • @jiangcaiyang 你好,这个我下了,我尝试过用CMake build这个,然后用VS打开是正常的,但我很想在QT Creator 弄OBS。
    首先我不知道你这个界面是在哪弹出来的,看起来有些像CMake的配置界面但又不是,Creator里面也没看到这个界面,我一开始没有找到你这个界面于是就没有设置以来的那个deps,但是在编译错误之后,我手动在CMakeList.txt中设置了 depspath变量,然后build就顺利完成了,可最后运行的时候却又发生了我留言的错误,现在问题依然没解决



  • @tobin 这个界面就是Qt Creator的。很简单。在Qt Creator项目选项卡里,选择构建,有一个CMake选项卡,即是我截图中的效果。
    0_1521729016550_e901b625-c635-47ef-8d8c-7cd1671e15a9-image.png



  • @tobin 要是用cmake的话,我觉得clion更方便些



  • @tobin 我和你有同样的问题,而且用qt打开cmakelist不能配置会出现这样的错误:

    D:\Win\Program Files\CMake\share\cmake-3.11\Modules\CMakeTestCCompiler.cmake:52: error: The C compiler "C:/Program Files (x86)/Microsoft Visual Studio/2017/Enterprise/VC/Tools/MSVC/14.13.26128/bin/HostX64/x64/cl.exe" is not able to compile a simple test program. It fails with the following output: Change Dir: C:/Users/siku/AppData/Local/Temp/QtCreator-jpeRAp/qtc-cmake-JttTcaLu/CMakeFiles/CMakeTmp Run Build Command:"jom" "/NOLOGO" "cmTC_dc326\fast" 系统找不到指定的文件。 Generator: execution of make failed. Make command was: "jom" "/NOLOGO" "cmTC_dc326\fast"
    

    它的cmake generator是这个:
    0_1523967732514_ff052971-47eb-49c4-9984-eda331c7d8ed-image.png
    我修改成:
    0_1523967767408_85221fe4-b6fd-44d3-8ba0-26b62efa19d4-image.png
    以后会出现这样的错误:

    :-1: error: Failed to activate protocol version: "CMAKE_GENERATOR" is set but incompatible with configured generator value.
    

    只有用过cmake-gui然后才能正确的camke,但是会弹出这个:
    0_1523968068547_0e47719e-8620-4689-9dde-5970563250a0-image.png
    gu关闭以后就ok

    然后和你是一样的错误

    MSBUILD:-1: error: MSB1009: 项目文件不存在。
    

    我的环境是:

    win10 x64
    vs2017 x64
    qt5.10.1 msvc 64
    cmake3.11
    


  • @siku 这个是obs项目吗?英文字符好多,我有点儿迷~
    0_1523969318077_QQ图片20180417204829.jpg



  • @tobin 顺便我不会cmake,请问你怎么添加的?



  • @jiangcaiyang 嗯,我也看不懂直接复制的



  • @siku 我写了一个简单的cmake教程,给你一个链接吧。:face_with_stuck-out_tongue_closed_eyes:
    还有呢。





  • @siku 我们论坛还有一些资源,使用搜索功能就容易找到的。



  • @jiangcaiyang 讲真,qt creator编译obs-studio真的很迷。
    对了,你msbuild项目不存在的问题解决了吗?



  • @jiangcaiyang 看到了,浏览ing


Log in to reply
 

走马观花

最近的回复

  • Qt for MCUs

    搭建Qt for MCUs PC端开发环境。qt for mcus提供了一个完整的图形框架和工具包,包含了在MCUs上设计、开发和部署gui所需的一切。它允许您在裸机或实时操作系统上运行应用程序。

    先决条件

    开发主机环境支持仅限于Windows 10

    MSVC compiler v19.16 (Visual Studio 2017 15.9.9 or newer) x64

    CMake v3.13 or newer (you can install it using the Qt Online installer) x64

    使用Qt联机安装程序安装Qt for MCUs,该安装程序可通过Qt帐户下载

    安装Qt 5.14和Qt Creator 4.11 or higher

    安装链接

    › Qt: https://account.qt.io/downloads
    › CMake: https://cmake.org/download/
    › Python 2.7 32-bit: https://www.python.org/downloads/release/python-2716/
    › Arm GCC: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnutoolchain/gnu-rm/downloads
    › J-Link Software Pack: https://www.segger.com/downloads/jlink/JLink_Windows.exe
    › J-Link OpenSDA Firmware: https://www.segger.com/downloads/jlink/OpenSDA_MIMXRT1050-EVKHyperflash
    › STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html
    › STM32 ST-LINK Utility: https://www.st.com/en/development-tools/stsw-link004.html​​​​​​​

    Qt Creator设置 启用Qt Creator插件 选择“帮助>关于插件”,然后从列表中选择“MCU支持(实验性)”插件,重新启动Qt Creator以应用更改
    替代文字 为MCU创建Qt工具包

    选择工具>选项>设备>MCU

    选择Qt for MCUs-Desktop 32bpp作为目标

    如果尚未设置,请提供Qt for MCUs安装目录的路径。

    单击Apply应用。

    替代文字

    替代文字
    替代文字

    注意:

    编译器要选X64,Qt版本要选64bit,CMake Tool选x64

    打开恒温器项目demo

    选择文件>打开文件或项目。。。

    打开CMakefiles.txt文件来自thermo文件夹的文件。

    选择Qt作为MCU-桌面32bpp套件。

    单击“配置项目”以完成。

    替代文字

    问题

    开发主机环境支持仅限于Windows 10

    C++编译失败,文本大字体.pixelSize.

    文本类型无法正确呈现需要复杂文本布局的unicode序列。对复杂文本使用StaticText

    read more
  • H

    hi 有问题请教你,方便加个联系方式吗

    read more
  • boost.asio是一个很棒的网络库,这回儿我也开始系统地学习起来了。想想当年接触boost,也有八年多了。这次开始接触boost,觉得既熟悉又陌生。熟悉的是小写字母+下划线的命名方式、晦涩的模板、很慢的编译速度以及较大的程序体积,陌生的是asio的各种概念:io服务、接收器、套接字等等:我之前对网络编程不是非常了解。

    于是根据我的理解,参考《Boost.Asio C++网络编程》实现了这样一个简单的客户端和服务端通信的例子,例子非常简单,还不完善,但是幸运的是,可以在本机上互通了。
    下面是客户端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void writeHandler( const boost::system::error_code& ec, size_t bytesTransferred ) { if ( ec ) { cout << "Write data error, code: " << ec.value( ) << "transferred: " << bytesTransferred << endl; } else { cout << "OK! " << bytesTransferred << "bytes written. " << endl; } } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::socket sock( service ); ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; sock.connect( ep, ec ); if ( ec ) { cout << "Connect error, code: " << ec.value( ) << ", We will exit." << endl; return ec.value( ); } else { char buf[1024] = "Hello world!"; sock.async_write_some( buffer( buf ), writeHandler ); sock.close( ); } return service.run( ); }

    下面是服务端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void acceptHandle( const boost::system::error_code& code ) { cout << "Accepted." << endl; } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; ip::tcp::socket sock( service ); ip::tcp::acceptor acceptor( service, ep ); acceptor.async_accept( sock, acceptHandle ); if ( ec ) { cout << "There is an error in server. code: " << ec.value( ) << endl; } return service.run( );// 阻塞运行 }

    运行结果是这样的:
    78448d7b-b3ae-42fc-9e2e-4dd2fbdac2c2-image.png

    我对boost.asio中几个概念的理解:

    io_service,这就是一个类似事件循环的东西,它为io设备提供服务,故名。不管是套接字、文件还是串口设备,都要使用它的服务。它的run()函数相当于启动了一个事件循环。一旦有消息了,即进行响应。这也是实现异步编程的重要基础。 socket,这个类则是套接字,可以处理TCP或者是UDP请求。有同步以及异步的处理方式,也有带异常以及不带异常的处理方式。 acceptor,接收器,仅仅是服务端使用。相当于其余框架中的listener,作接收用的。

    比较浅显,如果有不当之处,敬请指正。

    read more
  • 843143141.jpg
    闲下来了,我又开始大规模地学习了。
    最近开始学习内存模型和无锁结构。因为这个是和操作系统密切相关的,懂得这些对于编写C++服务端应用程序
    有着非常好的帮助。之前我对内存模型以及无锁结构几乎没有什么了解,我就询问群里的大佬看看有没有可以参考的资料。
    大佬很高兴,并且推荐了我一本名为《Memory Model》的电子书。这本电子书虽然页数不多,但是从起源到发展,
    从源码到汇编,都给我们详细地介绍了。看了一遍,不是非常理解,但是依然尝试将自己的理解写下来,以便日后翻阅。
    首先因为多核处理器成为主流,多线程的程序已经非常常见,因此我们不可避免地要处理多线程程序的同步问题。
    然后,因为编译器默认都对源码进行了优化,在单核处理器中这通常不是什么问题,但是在多核处理器中,就会因为编译器
    对其进行了乱序处理而导致程序出现问题。由此深入地探讨内存模型。
    内存模型主要分为:
    载-载 顺序(load-load order)
    载-存 顺序(load-store order)
    存-载 顺序(store-load order)
    存-存 顺序(store-store order)
    依赖载入顺序(dependent loads order)

    通过内存栅栏(memory barrier)能够避免编译器对指令的乱序。Linux中有

    READ_ONCE( x, value ) WRITE_ONCE( x )

    避免这些读写被编译器乱序或者是优化掉。

    这里谈到volatile关键字。在另外一篇博客上说,volatile具有“易变性、不可优化性、顺序性”。简单说,由于
    被volatile声明的变量,指令须从内存读取,并且不能被编译器乱序以及优化。在Java(语言扩展)和MSVC(系统兼容)上,
    还附带了Accquire()和Release()语义,因此可部分用于多线程环境。但多数情况下,还是慎用volatile,
    因为不同架构的处理器,它的内存模型是千变万化的,不能一而概之。

    至于C++11,它提供了std::atomic<T>这个模板类,相当于提供了很多方式来实现不同内存模型的原子操作。
    它的load()和store()方法,第二个参数有以下几个选项:

    std::memory_order_relaxed std::memory_order_seq_cst std::memory_order_acq_rel std::memory_order_acquire std::memory_order_release std::memory_order_consume

    我们最常用来实现RCpc(Release Consistency、Processor Consistency)是使用

    std::memory_order_acquire std::memory_order_release

    这两对。

    作为例子,在实现自旋锁时使用std::atomic<T>是这样的:

    struct SpinLock2 { void lock( ) { for ( ; ; ) { while ( lock_.load( std::memory_order_relaxed ) ); if ( !lock_.exchange( true, std::memory_order_acquire ) ) break; } } void unlock( ) { lock_.store( false, std::memory_order_release ); } std::atomic<bool> lock_ = { false }; };

    read more

关注我们

微博
QQ群