Skip to content

Commit 44a3423

Browse files
authored
livekit-plugins-browser (#248)
1 parent 2bba663 commit 44a3423

19 files changed

+1118
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CMakeLists.txt.user
2+
CMakeCache.txt
3+
CMakeFiles
4+
CMakeScripts
5+
Testing
6+
Makefile
7+
cmake_install.cmake
8+
install_manifest.txt
9+
compile_commands.json
10+
CTestTestfile.cmake
11+
_deps
12+
/build
13+
/third_party/cef/
14+
/src/Release
15+
/src/*.plist
16+
/*.plist
17+
/libcef_dll_wrapper
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
cmake_minimum_required(VERSION 3.19)
2+
set(CMAKE_CONFIGURATION_TYPES Debug Release)
3+
4+
project(livekit-cef)
5+
set_property(GLOBAL PROPERTY OS_FOLDERS ON)
6+
7+
set(CMAKE_CXX_STANDARD 17)
8+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # useful for clangd as the language server
9+
set(USE_SANDBOX OFF) # TODO(theomonnom): I don't think we want to enable sandbox
10+
# for now, it add complexity
11+
12+
# Specify the CEF distribution version.
13+
if(NOT DEFINED CEF_VERSION)
14+
set(CEF_VERSION "122.1.10+gc902316+chromium-122.0.6261.112")
15+
endif()
16+
17+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
18+
if("${PROJECT_ARCH}" STREQUAL "arm64")
19+
set(CEF_PLATFORM "macosarm64")
20+
elseif("${PROJECT_ARCH}" STREQUAL "x86_64")
21+
set(CEF_PLATFORM "macosx64")
22+
elseif("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64")
23+
set(PROJECT_ARCH "arm64")
24+
set(CEF_PLATFORM "macosarm64")
25+
else()
26+
set(PROJECT_ARCH "x86_64")
27+
set(CEF_PLATFORM "macosx64")
28+
endif()
29+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
30+
if(CMAKE_SIZEOF_VOID_P MATCHES 8)
31+
set(CEF_PLATFORM "linux64")
32+
else()
33+
set(CEF_PLATFORM "linux32")
34+
endif()
35+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
36+
if(CMAKE_SIZEOF_VOID_P MATCHES 8)
37+
set(CEF_PLATFORM "windows64")
38+
else()
39+
set(CEF_PLATFORM "windows32")
40+
endif()
41+
endif()
42+
43+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
44+
45+
# Download and extract the CEF binary distribution (executes DownloadCEF.cmake).
46+
include(DownloadCEF)
47+
downloadcef("${CEF_PLATFORM}" "${CEF_VERSION}"
48+
"${CMAKE_SOURCE_DIR}/third_party/cef")
49+
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CEF_ROOT}/cmake")
50+
51+
# Load the CEF configuration (executes FindCEF.cmake).
52+
find_package(CEF REQUIRED)
53+
54+
# Python
55+
find_package(PythonInterp REQUIRED)
56+
find_package(pybind11 REQUIRED)
57+
58+
message(STATUS "Using Python: ${PYTHON_EXECUTABLE}")
59+
60+
add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper)
61+
add_subdirectory(src)
62+
63+
print_cef_config()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2008-2016 Marshall A. Greenblatt. Portions Copyright (c)
2+
// 2006-2009 Google Inc. All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are
6+
// met:
7+
//
8+
// * Redistributions of source code must retain the above copyright
9+
// notice, this list of conditions and the following disclaimer.
10+
// * Redistributions in binary form must reproduce the above
11+
// copyright notice, this list of conditions and the following disclaimer
12+
// in the documentation and/or other materials provided with the
13+
// distribution.
14+
// * Neither the name of Google Inc. nor the name Chromium Embedded
15+
// Framework nor the names of its contributors may be used to endorse
16+
// or promote products derived from this software without specific prior
17+
// written permission.
18+
//
19+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
2+
# reserved. Use of this source code is governed by a BSD-style license that
3+
# can be found in the LICENSE file.
4+
5+
# Download the CEF binary distribution for |platform| and |version| to
6+
# |download_dir|. The |CEF_ROOT| variable will be set in global scope pointing
7+
# to the extracted location.
8+
# Visit https://cef-builds.spotifycdn.com/index.html for the list of
9+
# supported platforms and versions.
10+
11+
function(DownloadCEF platform version download_dir)
12+
# Specify the binary distribution type and download directory.
13+
set(CEF_DISTRIBUTION "cef_binary_${version}_${platform}")
14+
set(CEF_DOWNLOAD_DIR "${download_dir}")
15+
16+
# The location where we expect the extracted binary distribution.
17+
set(CEF_ROOT "${CEF_DOWNLOAD_DIR}/${CEF_DISTRIBUTION}" CACHE INTERNAL "CEF_ROOT")
18+
19+
# Download and/or extract the binary distribution if necessary.
20+
if(NOT IS_DIRECTORY "${CEF_ROOT}")
21+
set(CEF_DOWNLOAD_FILENAME "${CEF_DISTRIBUTION}.tar.bz2")
22+
set(CEF_DOWNLOAD_PATH "${CEF_DOWNLOAD_DIR}/${CEF_DOWNLOAD_FILENAME}")
23+
if(NOT EXISTS "${CEF_DOWNLOAD_PATH}")
24+
set(CEF_DOWNLOAD_URL "https://cef-builds.spotifycdn.com/${CEF_DOWNLOAD_FILENAME}")
25+
string(REPLACE "+" "%2B" CEF_DOWNLOAD_URL_ESCAPED ${CEF_DOWNLOAD_URL})
26+
27+
# Download the SHA1 hash for the binary distribution.
28+
message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}.sha1 from ${CEF_DOWNLOAD_URL_ESCAPED}...")
29+
file(DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}.sha1" "${CEF_DOWNLOAD_PATH}.sha1")
30+
file(READ "${CEF_DOWNLOAD_PATH}.sha1" CEF_SHA1)
31+
32+
# Download the binary distribution and verify the hash.
33+
message(STATUS "Downloading ${CEF_DOWNLOAD_PATH}...")
34+
file(
35+
DOWNLOAD "${CEF_DOWNLOAD_URL_ESCAPED}" "${CEF_DOWNLOAD_PATH}"
36+
EXPECTED_HASH SHA1=${CEF_SHA1}
37+
SHOW_PROGRESS
38+
)
39+
endif()
40+
41+
# Extract the binary distribution.
42+
message(STATUS "Extracting ${CEF_DOWNLOAD_PATH}...")
43+
execute_process(
44+
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CEF_DOWNLOAD_DIR}/${CEF_DOWNLOAD_FILENAME}"
45+
WORKING_DIRECTORY ${CEF_DOWNLOAD_DIR}
46+
)
47+
endif()
48+
endfunction()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
set(LKCEF_SRCS app.cpp app.hpp utils.cpp utils.hpp handler.hpp handler.cpp)
2+
set(LKCEF_SRCS_LINUX main_linux.cpp)
3+
set(LKCEF_SRCS_MAC main_mac.mm handler_mac.mm app_mac.mm)
4+
set(LKCEF_SRCS_WINDOWS main_win.cpp )
5+
append_platform_sources(LKCEF_SRCS)
6+
source_group(lkcef FILES ${LKCEF_SRCS})
7+
8+
set(LKCEF_HELPER_SRCS utils.cpp utils.hpp)
9+
set(LKCEF_HELPER_SRCS_LINUX helper_main_linux.cpp)
10+
set(LKCEF_HELPER_SRCS_MAC helper_main_mac.mm)
11+
set(LKCEF_HELPER_SRCS_WINDOWS helper_main_win.cpp)
12+
append_platform_sources(LKCEF_HELPER_SRCS)
13+
source_group(lkcef FILES ${LKCEF_HELPER_SRCS})
14+
15+
set(LKCEF_PYTHON_SRCS agents_python.hpp
16+
agents_python.cpp)
17+
18+
if(OS_LINUX OR OS_WINDOWS)
19+
# Logical target used to link the libcef library on Linux and Windows. On
20+
# macOS the CEF framework is loaded dynamically at startup.
21+
add_logical_target("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
22+
endif()
23+
24+
set_cef_target_out_dir() # Determine the target output directory.
25+
26+
if(OS_LINUX)
27+
# Helper executable target.
28+
add_executable(lkcef_helper ${LKCEF_HELPER_SRCS})
29+
set_executable_target_properties(lkcef_helper)
30+
add_dependencies(lkcef_helper libcef_dll_wrapper)
31+
target_link_libraries(lkcef_helper libcef_lib libcef_dll_wrapper
32+
${CEF_STANDARD_LIBS})
33+
34+
# Set rpath so that libraries can be placed next to the executable.
35+
set_target_properties(lkcef_helper PROPERTIES INSTALL_RPATH "$ORIGIN")
36+
set_target_properties(lkcef_helper PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
37+
38+
# library target.
39+
add_library(lkcef SHARED ${LKCEF_SRCS})
40+
set_library_target_properties(lkcef)
41+
add_dependencies(lkcef libcef_dll_wrapper lkcef_helper)
42+
target_link_libraries(lkcef libcef_lib libcef_dll_wrapper
43+
${CEF_STANDARD_LIBS})
44+
45+
# Set rpath so that libraries can be placed next to the library.
46+
set_target_properties(lkcef PROPERTIES INSTALL_RPATH "$ORIGIN")
47+
set_target_properties(lkcef PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
48+
49+
# Copy binary and resource files to the target output directory.
50+
copy_files("lkcef" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}"
51+
"${CEF_TARGET_OUT_DIR}")
52+
copy_files("lkcef" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}"
53+
"${CEF_TARGET_OUT_DIR}")
54+
endif()
55+
56+
if(OS_MAC)
57+
# Avoid CMP0042 policy errors.
58+
set(CMAKE_MACOSX_RPATH 1)
59+
60+
# Avoid CMP0068 policy errors.
61+
if(POLICY CMP0068)
62+
cmake_policy(SET CMP0068 NEW)
63+
endif()
64+
65+
# output path for the main app bundle.
66+
set(LKCEF_APP "${CEF_TARGET_OUT_DIR}/lkcef_app.app")
67+
68+
# library target.
69+
add_library(lkcef STATIC ${LKCEF_SRCS})
70+
set_library_target_properties(lkcef)
71+
add_dependencies(lkcef libcef_dll_wrapper)
72+
target_link_libraries(lkcef libcef_dll_wrapper ${CEF_STANDARD_LIBS})
73+
74+
75+
76+
add_custom_command(
77+
TARGET lkcef
78+
POST_BUILD
79+
# Copy the CEF framework into the main app bundle.
80+
COMMAND
81+
${CMAKE_COMMAND} -E copy_directory
82+
"${CEF_BINARY_DIR}/Chromium Embedded Framework.framework"
83+
"${LKCEF_APP}/Contents/Frameworks/Chromium Embedded Framework.framework"
84+
# Copy the library into the main app bindle. COMMAND ${CMAKE_COMMAND} -E
85+
# copy_if_different "${CEF_TARGET_OUT_DIR}/liblkcef.dylib"
86+
# "${LKCEF_APP}/Contents/MacOS/liblkcef.dylib"
87+
VERBATIM)
88+
89+
# Create the multiple Helper app bundle targets.
90+
foreach(_suffix_list ${CEF_HELPER_APP_SUFFIXES})
91+
# Convert to a list and extract the suffix values.
92+
string(REPLACE ":" ";" _suffix_list ${_suffix_list})
93+
list(GET _suffix_list 0 _name_suffix)
94+
list(GET _suffix_list 1 _target_suffix)
95+
list(GET _suffix_list 2 _plist_suffix)
96+
97+
# Define Helper target and output names.
98+
set(_helper_target "lkcef_Helper${_target_suffix}")
99+
set(_helper_output_name "lkcef Helper${_name_suffix}")
100+
101+
# Create Helper-specific variants of the helper-Info.plist file.
102+
set(_helper_info_plist
103+
"${CMAKE_CURRENT_BINARY_DIR}/lkcef-Info${_target_suffix}.plist")
104+
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/resources/lkcef-Info.plist"
105+
_plist_contents)
106+
string(REPLACE "\${EXECUTABLE_NAME}" "${_helper_output_name}"
107+
_plist_contents ${_plist_contents})
108+
string(REPLACE "\${PRODUCT_NAME}" "${_helper_output_name}" _plist_contents
109+
${_plist_contents})
110+
string(REPLACE "\${BUNDLE_ID_SUFFIX}" "${_plist_suffix}" _plist_contents
111+
${_plist_contents})
112+
file(WRITE ${_helper_info_plist} ${_plist_contents})
113+
114+
# Create Helper executable target.
115+
add_executable(${_helper_target} MACOSX_BUNDLE ${LKCEF_HELPER_SRCS})
116+
set_executable_target_properties(${_helper_target})
117+
add_dependencies(${_helper_target} libcef_dll_wrapper)
118+
target_link_libraries(${_helper_target} libcef_dll_wrapper
119+
${CEF_STANDARD_LIBS})
120+
set_target_properties(
121+
${_helper_target}
122+
PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${_helper_info_plist}
123+
OUTPUT_NAME ${_helper_output_name})
124+
125+
# Add the Helper as a dependency of the main executable target.
126+
add_dependencies(lkcef "${_helper_target}")
127+
128+
# Copy the Helper app bundle into the Frameworks directory.
129+
add_custom_command(
130+
TARGET lkcef
131+
POST_BUILD
132+
COMMAND
133+
${CMAKE_COMMAND} -E copy_directory
134+
"${CEF_TARGET_OUT_DIR}/${_helper_output_name}.app"
135+
"${LKCEF_APP}/Contents/Frameworks/${_helper_output_name}.app"
136+
VERBATIM)
137+
endforeach()
138+
endif()
139+
140+
if(OS_WINDOWS)
141+
# Helper executable target.
142+
add_executable(lkcef_helper WIN32 ${LKCEF_HELPER_SRCS})
143+
set_executable_target_properties(lkcef_helper)
144+
add_dependencies(lkcef_helper libcef_dll_wrapper)
145+
target_link_libraries(lkcef_helper libcef_lib libcef_dll_wrapper
146+
${CEF_STANDARD_LIBS})
147+
148+
# library target.
149+
add_library(lkcef SHARED ${LKCEF_SRCS})
150+
set_library_target_properties(lkcef)
151+
add_dependencies(lkcef libcef_dll_wrapper lkcef_helper)
152+
target_link_libraries(lkcef libcef_lib libcef_dll_wrapper
153+
${CEF_STANDARD_LIBS})
154+
155+
# Add the custom manifest files to the DLL and helper EXE.
156+
add_windows_manifest("${CMAKE_CURRENT_SOURCE_DIR}" "lkcef" "dll")
157+
add_windows_manifest("${CMAKE_CURRENT_SOURCE_DIR}" "lkcef_helper" "exe")
158+
159+
# Copy binary and resource files to the target output directory.
160+
copy_files("lkcef" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}"
161+
"${CEF_TARGET_OUT_DIR}")
162+
copy_files("lkcef" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}"
163+
"${CEF_TARGET_OUT_DIR}")
164+
endif()
165+
166+
167+
# TODO(theomonnom): should be pretty similar for NodeJS
168+
pybind11_add_module(lkcef_python ${LKCEF_PYTHON_SRCS})
169+
170+
set_target_properties(lkcef_python PROPERTIES INSTALL_RPATH "$ORIGIN")
171+
set_target_properties(lkcef_python PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
172+
173+
target_include_directories(lkcef_python PRIVATE ${CEF_INCLUDE_PATH})
174+
target_link_libraries(lkcef_python PUBLIC lkcef)
175+
target_link_libraries(lkcef_python PUBLIC libcef_dll_wrapper ${CEF_STANDARD_LIBS})
176+
177+
178+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include "agents_python.hpp"
2+
3+
#include "app.hpp"
4+
#include "include/internal/cef_mac.h"
5+
6+
namespace py = pybind11;
7+
8+
BrowserImpl::BrowserImpl() {
9+
10+
}
11+
12+
13+
void BrowserImpl::start() {
14+
py::print("BrowserImpl::start()");
15+
AgentApp::run();
16+
}
17+
18+
19+
PYBIND11_MODULE(lkcef_python, m)
20+
{
21+
m.doc() = "Chromium Embedded Framework (CEF) for LiveKit Agents";
22+
23+
24+
py::class_<BrowserImpl>(m, "BrowserImpl")
25+
.def(py::init<>())
26+
.def("start", &BrowserImpl::start);
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef LKCEF_AGENT_PYTHON_HPP
2+
#define LKCEF_AGENT_PYTHON_HPP
3+
4+
#include <pybind11/pybind11.h>
5+
6+
7+
class BrowserImpl {
8+
public:
9+
BrowserImpl();
10+
void start();
11+
};
12+
13+
#endif // LKCEF_AGENT_PYTHON_HPP

0 commit comments

Comments
 (0)