mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-19 06:53:02 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e168d900f2 | ||
|
|
bc03e3be2f | ||
|
|
f224b8e4a6 | ||
|
|
8b479c9af3 | ||
|
|
d8299c388e | ||
|
|
4d85b6627e |
Vendored
+1
-1
@@ -238,7 +238,7 @@ if (NOT IS_CROSS_COMPILE OR NOT APPLE)
|
||||
DEPENDEES download # do after download
|
||||
COMMENT "Freeing Space: Removing source archive"
|
||||
WORKING_DIRECTORY ${DEP_DOWNLOAD_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -r ${projectname}
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf ${projectname}
|
||||
)
|
||||
ExternalProject_Add_Step(dep_${projectname} free_build_space
|
||||
DEPENDEES install # do after install
|
||||
|
||||
Vendored
+20
-4
@@ -1,6 +1,25 @@
|
||||
# libdatachannel is the native ICE/DTLS/SCTP implementation used by the
|
||||
# GUI WebRTC camera controller. Keep the source revision fixed: the signaling
|
||||
# protocol is evolving independently of this transport dependency.
|
||||
#
|
||||
# It vendors plog, usrsctp and libjuice as git submodules, which a plain
|
||||
# GitHub tag tarball does not include. The flatpak sandbox has no network
|
||||
# access during the build, so there the manifest itself clones the repo
|
||||
# (submodules and all) straight into this ExternalProject's default source
|
||||
# dir before the sandbox closes; with no download method given here and that
|
||||
# dir already non-empty, ExternalProject_Add silently uses it as-is instead
|
||||
# of trying its own (network) git step.
|
||||
if (FLATPAK)
|
||||
set(_datachannel_source "")
|
||||
else()
|
||||
set(_datachannel_source
|
||||
GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git
|
||||
GIT_TAG v0.24.5
|
||||
GIT_SHALLOW ON
|
||||
GIT_SUBMODULES_RECURSE ON
|
||||
)
|
||||
endif()
|
||||
|
||||
orcaslicer_add_cmake_project(DataChannel
|
||||
DEPENDS ${OPENSSL_PKG}
|
||||
CMAKE_ARGS
|
||||
@@ -13,8 +32,5 @@ orcaslicer_add_cmake_project(DataChannel
|
||||
-DUSE_SYSTEM_USRSCTP=OFF
|
||||
-DOPENSSL_ROOT_DIR:PATH=${DESTDIR}
|
||||
-DOPENSSL_USE_STATIC_LIBS=ON
|
||||
GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git
|
||||
GIT_TAG v0.22.2
|
||||
GIT_SHALLOW ON
|
||||
GIT_SUBMODULES_RECURSE ON
|
||||
${_datachannel_source}
|
||||
)
|
||||
|
||||
@@ -325,11 +325,16 @@ modules:
|
||||
sha256: deedcabe339165214a3637df4c86a507aef0d793cf8774ff68735f4737e8ddbc
|
||||
dest: external-packages/FFMPEG
|
||||
|
||||
# libdatachannel v0.22.2
|
||||
# libdatachannel v0.24.5
|
||||
# Use git instead of archive: it vendors plog, usrsctp and libjuice as
|
||||
# git submodules, which a plain GitHub tag tarball does not include.
|
||||
# Cloned (with submodules) straight into the ExternalProject source dir
|
||||
# that deps/DataChannel/DataChannel.cmake expects, since the sandboxed
|
||||
# build step has no network to do this itself.
|
||||
- type: git
|
||||
url: https://github.com/paullouisageneau/libdatachannel.git
|
||||
tag: v0.22.2
|
||||
commit: b3390b4e01e97071dd054684870c4bb5221794bf
|
||||
tag: v0.24.5
|
||||
commit: 443f6934d9007eb7076ab7825ba330f355fcbead
|
||||
dest: deps/build_flatpak/dep_DataChannel-prefix/src/dep_DataChannel
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
@@ -583,7 +583,7 @@ namespace Slic3r
|
||||
<< " printer_agent_id=" << it->second->printer_agent_id
|
||||
<< " connection_type=" << it->second->connection_type()
|
||||
<< " dev_connection_type=" << it->second->dev_connection_type;
|
||||
} else {
|
||||
} else if (!dev_id.empty()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Orca diagnostic: target machine was not found in the current agent's machine list";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1487,29 +1487,17 @@ int MachineObject::command_upgrade_module(std::string url, std::string module_ty
|
||||
|
||||
int MachineObject::command_xyz_abs()
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_xyz_abs(get_dev_id(), MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_xyz_abs(get_dev_id(), MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_auto_leveling()
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_auto_leveling(get_dev_id(), MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_auto_leveling(get_dev_id(), MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_go_home()
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_go_home(get_dev_id(), this->is_in_printing(), m_support_mqtt_homing, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_go_home(get_dev_id(), this->is_in_printing(), m_support_mqtt_homing, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_task_partskip(std::vector<int> part_ids)
|
||||
@@ -1631,20 +1619,12 @@ int MachineObject::command_stop_buzzer()
|
||||
|
||||
int MachineObject::command_set_bed(int temp)
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_set_bed(get_dev_id(), temp, m_support_mqtt_bet_ctrl, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_set_bed(get_dev_id(), temp, m_support_mqtt_bet_ctrl, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_set_nozzle(int temp)
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_set_nozzle(get_dev_id(), temp, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_set_nozzle(get_dev_id(), temp, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_set_nozzle_new(int nozzle_id, int temp)
|
||||
@@ -1749,11 +1729,7 @@ int MachineObject::command_ams_user_settings(bool start_read_opt, bool tray_read
|
||||
|
||||
int MachineObject::command_ams_calibrate(int ams_id)
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_ams_calibrate(get_dev_id(), ams_id, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_ams_calibrate(get_dev_id(), ams_id, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_filament_settings(int ams_id, int slot_id, std::string filament_id, std::string setting_id, std::string tray_color, std::string tray_type, int nozzle_temp_min, int nozzle_temp_max)
|
||||
@@ -1791,11 +1767,7 @@ int MachineObject::command_ams_filament_settings(int ams_id, int slot_id, std::s
|
||||
|
||||
int MachineObject::command_ams_refresh_rfid(std::string tray_id)
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_ams_refresh_rfid(get_dev_id(), tray_id, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_ams_refresh_rfid(get_dev_id(), tray_id, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_refresh_rfid2(int ams_id, int slot_id)
|
||||
@@ -1817,11 +1789,7 @@ int MachineObject::command_start_camera()
|
||||
|
||||
int MachineObject::command_ams_select_tray(std::string tray_id)
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_ams_select_tray(get_dev_id(), tray_id, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_ams_select_tray(get_dev_id(), tray_id, MachineObject::m_sequence_id++, is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_ams_control(std::string action)
|
||||
@@ -1980,12 +1948,9 @@ int MachineObject::command_ams_air_print_detect(bool air_print_detect)
|
||||
|
||||
int MachineObject::command_axis_control(std::string axis, double unit, double input_val, int speed)
|
||||
{
|
||||
if (!m_agent) return -1;
|
||||
int rtn = m_agent->command_axis_control(get_dev_id(), axis, unit, input_val, speed, is_core_xy(),
|
||||
m_support_mqtt_axis_control, MachineObject::m_sequence_id++, is_lan_mode_printer());
|
||||
if (rtn == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || rtn == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(rtn);
|
||||
return rtn;
|
||||
return command_with_dialog(m_agent->command_axis_control(get_dev_id(), axis, unit, input_val, speed, is_core_xy(),
|
||||
m_support_mqtt_axis_control, MachineObject::m_sequence_id++,
|
||||
is_lan_mode_printer()));
|
||||
}
|
||||
|
||||
int MachineObject::command_extruder_control(int nozzle_id, double val)
|
||||
@@ -6045,6 +6010,15 @@ bool MachineObject::HasAms() const
|
||||
return m_fila_system->HasAms();
|
||||
}
|
||||
|
||||
int MachineObject::command_with_dialog(int cmd_result)
|
||||
{
|
||||
if (!m_agent)
|
||||
return -1;
|
||||
if (cmd_result == ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED || cmd_result == ORCA_NETWORK_ERR_CAP_NOT_AVAILABLE)
|
||||
show_unsupported_dlg(cmd_result);
|
||||
return cmd_result;
|
||||
}
|
||||
|
||||
void change_the_opacity(wxColour& colour)
|
||||
{
|
||||
if (colour.Alpha() == 255) {
|
||||
|
||||
@@ -976,7 +976,7 @@ public:
|
||||
void command_set_save_remote_print_file_to_storage(bool save);
|
||||
|
||||
private:
|
||||
|
||||
int command_with_dialog(int cmd_result);
|
||||
/* xcam door open check*/
|
||||
bool is_support_door_open_check = false;
|
||||
DoorOpenCheckState xcam_door_open_check = DoorOpenCheckState::DOOR_OPEN_CHECK_DISABLE;
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/uri.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <slic3r/Utils/IPrinterAgent.hpp>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class IMediaController
|
||||
@@ -16,13 +12,6 @@ public:
|
||||
|
||||
virtual void Load(wxURI url) = 0;
|
||||
|
||||
// The default keeps existing media controllers unaware of camera-specific modes.
|
||||
virtual void Load(wxURI url, CameraStreamMode mode)
|
||||
{
|
||||
(void) mode;
|
||||
Load(url);
|
||||
}
|
||||
|
||||
virtual void Play() = 0;
|
||||
|
||||
virtual void Stop() = 0;
|
||||
@@ -32,15 +21,6 @@ public:
|
||||
virtual int GetLastError() const { return {}; };
|
||||
|
||||
virtual wxSize GetVideoSize() const { return {}; };
|
||||
|
||||
virtual void StartSession(std::unique_ptr<ICameraSignalingChannel> channel)
|
||||
{
|
||||
(void) channel;
|
||||
}
|
||||
|
||||
virtual void StopSession() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
+188
-185
@@ -1,4 +1,6 @@
|
||||
#include "MediaPlayCtrl.h"
|
||||
#include "WebMediaController.hpp"
|
||||
#include "IPrinterAgent.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "Widgets/CheckBox.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
@@ -24,6 +26,7 @@
|
||||
#include <boost/nowide/fstream.hpp>
|
||||
#include <boost/nowide/utf8_codecvt.hpp>
|
||||
#include <slic3r/GUI/DeviceManager.hpp>
|
||||
#include <wx/mediactrl.h>
|
||||
#undef pid_t
|
||||
#include <boost/process.hpp>
|
||||
#ifdef __WIN32__
|
||||
@@ -52,6 +55,7 @@ namespace GUI {
|
||||
MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl3 *media_ctrl, const wxPoint &pos, const wxSize &size)
|
||||
: wxPanel(parent, wxID_ANY, pos, size)
|
||||
, m_media_ctrl(media_ctrl)
|
||||
, m_active_media_controller(media_ctrl)
|
||||
{
|
||||
SetLabel("MediaPlayCtrl");
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
@@ -98,7 +102,10 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl3 *media_ctrl, const w
|
||||
});
|
||||
|
||||
m_button_play->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &e) { TogglePlay(); });
|
||||
m_button_play->Bind(wxEVT_RIGHT_UP, [this](auto & e) { m_media_ctrl->Play(); });
|
||||
m_button_play->Bind(wxEVT_RIGHT_UP, [this](auto & e) {
|
||||
if (m_active_media_controller)
|
||||
m_active_media_controller->Play();
|
||||
});
|
||||
// Orca: live-view FAQ link binding removed (vendor URL)
|
||||
|
||||
Bind(wxEVT_RIGHT_UP, [this](auto & e) {
|
||||
@@ -143,14 +150,12 @@ MediaPlayCtrl::MediaPlayCtrl(wxWindow *parent, wxMediaCtrl3 *media_ctrl, const w
|
||||
|
||||
MediaPlayCtrl::~MediaPlayCtrl()
|
||||
{
|
||||
m_webrtc_stopping = true;
|
||||
if (m_webrtc_ctrl)
|
||||
m_webrtc_ctrl->StopSession();
|
||||
m_webrtc_ctrl->Stop();
|
||||
m_media_ctrl->EndExternalStream();
|
||||
m_webrtc_stopping = false;
|
||||
{
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back("<exit>");
|
||||
m_tasks.push_back({"<exit>", nullptr});
|
||||
m_cond.notify_all();
|
||||
}
|
||||
while (!m_thread.try_join_for(boost::chrono::milliseconds(10))) {
|
||||
@@ -163,6 +168,33 @@ MediaPlayCtrl::~MediaPlayCtrl()
|
||||
void MediaPlayCtrl::SetWebMediaController(IMediaController *ctrl)
|
||||
{
|
||||
m_web_ctrl = ctrl;
|
||||
set_active_media_controller(current_mode());
|
||||
}
|
||||
|
||||
void MediaPlayCtrl::set_active_media_controller(CameraStreamMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case CameraStreamMode::http_snapshot:
|
||||
if (auto *web_ctrl = dynamic_cast<WebMediaController *>(m_web_ctrl))
|
||||
web_ctrl->set_mode(mode);
|
||||
m_active_media_controller = m_web_ctrl;
|
||||
break;
|
||||
case CameraStreamMode::webrtc:
|
||||
if (!m_webrtc_ctrl) {
|
||||
m_webrtc_ctrl = std::make_unique<WebRtcMediaController>(
|
||||
[this](const wxImage& image, wxSize size) { m_media_ctrl->SetExternalFrame(image, size); },
|
||||
[this, token = std::weak_ptr<int>(m_token)](WebRtcMediaController::Status status) {
|
||||
if (token.expired())
|
||||
return;
|
||||
CallAfter([this, status] { on_webrtc_status(status); });
|
||||
});
|
||||
}
|
||||
m_active_media_controller = m_webrtc_ctrl.get();
|
||||
break;
|
||||
default:
|
||||
m_active_media_controller = m_media_ctrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CameraStreamMode MediaPlayCtrl::current_mode() const
|
||||
@@ -181,105 +213,96 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
|
||||
}
|
||||
m_last_mode = mode;
|
||||
}
|
||||
set_active_media_controller(mode);
|
||||
|
||||
switch (mode) {
|
||||
case CameraStreamMode::http:
|
||||
case CameraStreamMode::https:
|
||||
case CameraStreamMode::http_snapshot:
|
||||
case CameraStreamMode::rtsp: {
|
||||
std::string machine = obj ? obj->get_dev_id() : "";
|
||||
const bool uses_local_camera_url = mode == CameraStreamMode::http || mode == CameraStreamMode::https ||
|
||||
mode == CameraStreamMode::http_snapshot || mode == CameraStreamMode::rtsp;
|
||||
const bool uses_webrtc = mode == CameraStreamMode::webrtc;
|
||||
const std::string machine = obj ? obj->get_dev_id() : "";
|
||||
bool changed = false;
|
||||
|
||||
if (uses_local_camera_url) {
|
||||
auto agent = wxGetApp().getAgent();
|
||||
std::string url = agent ? agent->get_local_camera_stream_url() : "";
|
||||
m_camera_exists = !url.empty();
|
||||
Enable(obj && m_camera_exists);
|
||||
bool changed = machine != m_machine || url != m_agent_camera_url;
|
||||
m_machine = machine;
|
||||
changed = machine != m_machine || url != m_agent_camera_url;
|
||||
m_agent_camera_url = url;
|
||||
m_url = from_u8(url);
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
// A genuine machine/URL switch: not a failure, so drop any pending
|
||||
// failure back-off before (re)starting on the new target.
|
||||
m_web_user_stopped = false;
|
||||
m_failed_code = 0;
|
||||
m_failed_retry = 0;
|
||||
m_next_retry = wxDateTime();
|
||||
if (m_last_state != MEDIASTATE_IDLE)
|
||||
Stop(" ");
|
||||
return;
|
||||
}
|
||||
case CameraStreamMode::webrtc: {
|
||||
std::string machine = obj ? obj->get_dev_id() : "";
|
||||
m_url = from_u8(url);
|
||||
} else if (uses_webrtc) {
|
||||
m_camera_exists = obj != nullptr;
|
||||
Enable(obj != nullptr);
|
||||
const bool changed = machine != m_machine;
|
||||
changed = machine != m_machine;
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::SetMachineObject webrtc: changed=" << changed
|
||||
<< " last_state=" << m_last_state << " web_user_stopped=" << m_web_user_stopped;
|
||||
m_machine = machine;
|
||||
m_url.clear();
|
||||
m_agent_camera_url.clear();
|
||||
if (!changed) {
|
||||
} else {
|
||||
if (obj) {
|
||||
m_camera_exists = obj->has_ipcam;
|
||||
m_dev_ver = obj->get_ota_version();
|
||||
m_lan_mode = obj->is_lan_mode_printer();
|
||||
m_lan_proto = obj->liveview_local;
|
||||
m_remote_proto = obj->get_liveview_remote();
|
||||
m_lan_ip = obj->get_dev_ip();
|
||||
m_lan_passwd = obj->get_access_code();
|
||||
m_device_busy = obj->is_camera_busy_off();
|
||||
m_tutk_state = obj->tutk_state;
|
||||
|
||||
if (DevPrinterConfigUtil::get_printer_series_str(obj->printer_type) == "series_o" && BBLNetworkPlugin::instance().use_legacy_network()) {
|
||||
// Legacy plugin cannot support remote play for H2D, force using local mode
|
||||
m_remote_proto = LiveviewRemote::LVR_None;
|
||||
}
|
||||
} else {
|
||||
m_camera_exists = false;
|
||||
m_lan_mode = false;
|
||||
m_lan_proto = LiveviewLocal::LVL_None;
|
||||
m_lan_ip.clear();
|
||||
m_lan_passwd.clear();
|
||||
m_dev_ver.clear();
|
||||
m_tutk_state.clear();
|
||||
m_remote_proto = 0;
|
||||
m_device_busy = false;
|
||||
}
|
||||
Enable(obj && obj->is_info_ready() && obj->m_push_count > 0);
|
||||
if (machine == m_machine)
|
||||
return;
|
||||
|
||||
m_machine = machine;
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl switch machine: " << m_machine;
|
||||
m_disable_lan = false;
|
||||
m_failed_retry = 0;
|
||||
m_last_failed_codes.clear();
|
||||
m_last_user_play = wxDateTime::Now();
|
||||
std::string stream_url;
|
||||
if (get_stream_url(&stream_url)) {
|
||||
m_streaming = boost::algorithm::contains(stream_url, "device=" + m_machine);
|
||||
} else {
|
||||
m_streaming = false;
|
||||
}
|
||||
m_web_user_stopped = false;
|
||||
if (m_last_state != MEDIASTATE_IDLE)
|
||||
Stop(" ");
|
||||
if (m_next_retry.IsValid()) // Try open 2 seconds later, to avoid state conflict
|
||||
m_next_retry = wxDateTime::Now() + wxTimeSpan::Seconds(2);
|
||||
else
|
||||
SetStatus("", false);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::string machine = obj ? obj->get_dev_id() : "";
|
||||
if (obj) {
|
||||
m_camera_exists = obj->has_ipcam;
|
||||
m_dev_ver = obj->get_ota_version();
|
||||
m_lan_mode = obj->is_lan_mode_printer();
|
||||
m_lan_proto = obj->liveview_local;
|
||||
m_remote_proto = obj->get_liveview_remote();
|
||||
m_lan_ip = obj->get_dev_ip();
|
||||
m_lan_passwd = obj->get_access_code();
|
||||
m_device_busy = obj->is_camera_busy_off();
|
||||
m_tutk_state = obj->tutk_state;
|
||||
|
||||
if (DevPrinterConfigUtil::get_printer_series_str(obj->printer_type) == "series_o" && BBLNetworkPlugin::instance().use_legacy_network()) {
|
||||
// Legacy plugin cannot support remote play for H2D, force using local mode
|
||||
m_remote_proto = LiveviewRemote::LVR_None;
|
||||
}
|
||||
} else {
|
||||
m_camera_exists = false;
|
||||
m_lan_mode = false;
|
||||
m_lan_proto = LiveviewLocal::LVL_None;
|
||||
m_lan_ip.clear();
|
||||
m_lan_passwd.clear();
|
||||
m_dev_ver.clear();
|
||||
m_tutk_state.clear();
|
||||
m_remote_proto = 0;
|
||||
m_device_busy = false;
|
||||
}
|
||||
Enable(obj && obj->is_info_ready() && obj->m_push_count > 0);
|
||||
if (machine == m_machine) {
|
||||
return;
|
||||
}
|
||||
m_machine = machine;
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl switch machine: " << m_machine;
|
||||
m_disable_lan = false;
|
||||
m_failed_retry = 0;
|
||||
m_last_failed_codes.clear();
|
||||
m_last_user_play = wxDateTime::Now();
|
||||
std::string stream_url;
|
||||
if (get_stream_url(&stream_url)) {
|
||||
m_streaming = boost::algorithm::contains(stream_url, "device=" + m_machine);
|
||||
} else {
|
||||
m_streaming = false;
|
||||
if (!changed)
|
||||
return;
|
||||
|
||||
// A genuine target switch is not a stream failure and should clear the
|
||||
// manual-stop state before the new target is allowed to play.
|
||||
m_web_user_stopped = false;
|
||||
if (uses_local_camera_url) {
|
||||
m_failed_code = 0;
|
||||
m_failed_retry = 0;
|
||||
m_next_retry = wxDateTime();
|
||||
}
|
||||
if (m_last_state != MEDIASTATE_IDLE)
|
||||
Stop(" ");
|
||||
if (m_next_retry.IsValid()) // Try open 2 seconds later, to avoid state conflict
|
||||
m_next_retry = wxDateTime::Now() + wxTimeSpan::Seconds(2);
|
||||
else
|
||||
SetStatus("", false);
|
||||
}
|
||||
|
||||
wxString hide_id_middle_string(wxString const &str, size_t offset = 0, size_t length = -1)
|
||||
@@ -330,97 +353,71 @@ void refresh_agora_url(char const* device, char const* dev_ver, char const* chan
|
||||
|
||||
void MediaPlayCtrl::Play()
|
||||
{
|
||||
switch (current_mode()) {
|
||||
case CameraStreamMode::http_snapshot:
|
||||
if (!m_next_retry.IsValid() || wxDateTime::Now() < m_next_retry)
|
||||
if ((m_next_retry.IsValid() && wxDateTime::Now() < m_next_retry) || !IsShownOnScreen() || m_last_state != MEDIASTATE_IDLE)
|
||||
return;
|
||||
|
||||
const CameraStreamMode mode = current_mode();
|
||||
set_active_media_controller(mode);
|
||||
m_last_mode = mode;
|
||||
auto agent = wxGetApp().getAgent();
|
||||
|
||||
auto printer_agent = agent ? agent->get_printer_agent() : nullptr;
|
||||
const bool is_bbl = (printer_agent ? printer_agent->get_agent_info().id : "") == BBL_PRINTER_AGENT_ID;
|
||||
|
||||
if (!is_bbl) {
|
||||
const bool is_webrtc = mode == CameraStreamMode::webrtc;
|
||||
const bool is_snapshot = mode == CameraStreamMode::http_snapshot;
|
||||
const bool is_http_stream = mode == CameraStreamMode::http || mode == CameraStreamMode::https || mode == CameraStreamMode::rtsp;
|
||||
if (!is_webrtc && !is_snapshot && !is_http_stream)
|
||||
return;
|
||||
if (!IsShownOnScreen()) return;
|
||||
if (m_last_state != MEDIASTATE_IDLE) return;
|
||||
if (m_machine.empty() || !IsEnabled() || !m_camera_exists || m_url.IsEmpty() || !m_web_ctrl) {
|
||||
|
||||
auto *webrtc_ctrl = is_webrtc ? dynamic_cast<WebRtcMediaController *>(m_active_media_controller) : nullptr;
|
||||
if (is_webrtc && (!webrtc_ctrl || !m_media_ctrl)) {
|
||||
Stop(_L("Please confirm if the printer is connected."));
|
||||
return;
|
||||
}
|
||||
m_button_play->SetIcon("media_stop");
|
||||
m_web_ctrl->Load(wxURI(m_url), current_mode());
|
||||
m_web_ctrl->Play();
|
||||
m_last_state = wxMEDIASTATE_PLAYING;
|
||||
SetStatus(_L("Playing..."), false);
|
||||
return;
|
||||
case CameraStreamMode::http:
|
||||
case CameraStreamMode::https:
|
||||
case CameraStreamMode::rtsp:
|
||||
if (m_next_retry.IsValid() && wxDateTime::Now() < m_next_retry)
|
||||
if (webrtc_ctrl && webrtc_ctrl->is_active())
|
||||
return;
|
||||
if (!IsShownOnScreen()) return;
|
||||
if (m_last_state != MEDIASTATE_IDLE) return;
|
||||
|
||||
m_failed_code = 0;
|
||||
if (m_machine.empty() || !IsEnabled() || !m_camera_exists || m_url.IsEmpty()) {
|
||||
if (!m_active_media_controller || m_machine.empty() || !IsEnabled() || !m_camera_exists ||
|
||||
(!is_webrtc && m_url.IsEmpty())) {
|
||||
Stop(_L("Please confirm if the printer is connected."));
|
||||
return;
|
||||
}
|
||||
m_button_play->SetIcon("media_stop");
|
||||
load();
|
||||
return;
|
||||
case CameraStreamMode::webrtc: {
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::Play webrtc: last_state=" << m_last_state
|
||||
<< " next_retry_valid=" << m_next_retry.IsValid()
|
||||
<< " next_retry_future=" << (m_next_retry.IsValid() && wxDateTime::Now() < m_next_retry)
|
||||
<< " failed_retry=" << m_failed_retry << " shown=" << IsShownOnScreen();
|
||||
if (m_webrtc_ctrl && m_webrtc_ctrl->is_active()) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::Play webrtc: session already active, ignoring";
|
||||
return;
|
||||
}
|
||||
if (m_next_retry.IsValid() && wxDateTime::Now() < m_next_retry)
|
||||
return;
|
||||
if (!IsShownOnScreen() || m_last_state != MEDIASTATE_IDLE)
|
||||
return;
|
||||
m_failed_code = 0;
|
||||
if (m_machine.empty() || !IsEnabled() || !m_camera_exists) {
|
||||
Stop(_L("Please confirm if the printer is connected."));
|
||||
return;
|
||||
}
|
||||
auto agent = wxGetApp().getAgent();
|
||||
auto channel = agent ? agent->create_camera_signaling_channel(m_machine) : nullptr;
|
||||
if (!channel) {
|
||||
Stop(_L("Sign in to OrcaCloud to view the camera."));
|
||||
return;
|
||||
}
|
||||
if (!m_webrtc_ctrl) {
|
||||
m_webrtc_ctrl = std::make_unique<WebRtcMediaController>(
|
||||
[this](const wxImage& image, wxSize size) { m_media_ctrl->SetExternalFrame(image, size); },
|
||||
[this, token = std::weak_ptr<int>(m_token)](WebRtcMediaController::Status status) {
|
||||
if (token.expired())
|
||||
return;
|
||||
CallAfter([this, status] { on_webrtc_status(status); });
|
||||
});
|
||||
}
|
||||
m_button_play->SetIcon("media_stop");
|
||||
m_media_ctrl->BeginExternalStream();
|
||||
m_last_state = MEDIASTATE_INITIALIZING;
|
||||
SetStatus(_L("Initializing..."), false);
|
||||
m_webrtc_stopping = false;
|
||||
m_webrtc_ctrl->StartSession(std::move(channel));
|
||||
m_webrtc_epoch = m_webrtc_ctrl->epoch();
|
||||
return;
|
||||
}
|
||||
default: // assumed to be CameraStreamMode::none
|
||||
if (NetworkAgent* agent = wxGetApp().getAgent()) {
|
||||
if (auto printer_agent = agent->get_printer_agent()) {
|
||||
if (printer_agent->get_agent_info().id != BBL_PRINTER_AGENT_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_webrtc) {
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::Play webrtc: last_state=" << m_last_state << " failed_retry=" << m_failed_retry
|
||||
<< " shown=" << IsShownOnScreen();
|
||||
auto channel = agent ? agent->create_camera_signaling_channel(m_machine) : nullptr;
|
||||
if (!channel) {
|
||||
Stop(_L("Sign in to OrcaCloud to view the camera."));
|
||||
return;
|
||||
}
|
||||
webrtc_ctrl->set_signalling_channel(std::move(channel));
|
||||
m_media_ctrl->BeginExternalStream();
|
||||
m_last_state = MEDIASTATE_INITIALIZING;
|
||||
SetStatus(_L("Initializing..."), false);
|
||||
} else if (is_snapshot) {
|
||||
m_last_state = wxMEDIASTATE_PLAYING;
|
||||
SetStatus(_L("Playing..."), false);
|
||||
}
|
||||
break;
|
||||
|
||||
m_button_play->SetIcon("media_stop");
|
||||
if (m_active_media_controller == m_media_ctrl) {
|
||||
// wxMediaCtrl3 reports when it has a decoded frame; load() waits for
|
||||
// that event before queuing Play so the stream is not marked stopped.
|
||||
load();
|
||||
} else {
|
||||
m_active_media_controller->Load(wxURI(m_url));
|
||||
m_active_media_controller->Play();
|
||||
}
|
||||
if (webrtc_ctrl) {
|
||||
m_webrtc_epoch = webrtc_ctrl->epoch();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_next_retry.IsValid() || wxDateTime::Now() < m_next_retry)
|
||||
return;
|
||||
if (!IsShownOnScreen())
|
||||
return;
|
||||
if (m_last_state != MEDIASTATE_IDLE) {
|
||||
return;
|
||||
}
|
||||
m_failed_code = 0;
|
||||
if (m_machine.empty()) {
|
||||
Stop(_L("Please confirm if the printer is connected."));
|
||||
@@ -441,7 +438,6 @@ void MediaPlayCtrl::Play()
|
||||
}
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::Play: " << m_lan_proto << m_remote_proto << m_disable_lan;
|
||||
NetworkAgent *agent = wxGetApp().getAgent();
|
||||
std::string agent_version = agent ? agent->get_version() : "";
|
||||
if (m_lan_proto > LiveviewLocal::LVL_Disable && (m_lan_mode || !m_remote_proto) && !m_disable_lan && !m_lan_ip.empty()) {
|
||||
m_disable_lan = m_remote_proto && !m_lan_mode; // try remote next time
|
||||
@@ -545,8 +541,8 @@ void MediaPlayCtrl::StopWebStream()
|
||||
{
|
||||
if (m_last_state == MEDIASTATE_IDLE)
|
||||
return;
|
||||
if (m_web_ctrl)
|
||||
m_web_ctrl->Stop();
|
||||
if (m_active_media_controller && m_active_media_controller == m_web_ctrl)
|
||||
m_active_media_controller->Stop();
|
||||
m_button_play->SetIcon("media_play");
|
||||
m_last_state = MEDIASTATE_IDLE;
|
||||
SetStatus(_L("Video Stopped."), false);
|
||||
@@ -554,15 +550,14 @@ void MediaPlayCtrl::StopWebStream()
|
||||
|
||||
void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2)
|
||||
{
|
||||
const bool webrtc_active = m_webrtc_ctrl && m_last_mode == CameraStreamMode::webrtc;
|
||||
const bool webrtc_active = m_last_mode == CameraStreamMode::webrtc &&
|
||||
dynamic_cast<WebRtcMediaController *>(m_active_media_controller) != nullptr;
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::Stop: last_state=" << m_last_state
|
||||
<< " webrtc_active=" << webrtc_active << " failed_code=" << m_failed_code
|
||||
<< " msg='" << msg.ToUTF8().data() << "'";
|
||||
if (webrtc_active) {
|
||||
m_webrtc_stopping = true;
|
||||
m_webrtc_ctrl->StopSession();
|
||||
m_active_media_controller->Stop();
|
||||
m_media_ctrl->EndExternalStream();
|
||||
m_webrtc_stopping = false;
|
||||
}
|
||||
switch (m_last_mode) {
|
||||
case CameraStreamMode::http:
|
||||
@@ -571,13 +566,14 @@ void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2)
|
||||
const bool snapshot = m_last_mode == CameraStreamMode::http_snapshot;
|
||||
if (m_last_state != MEDIASTATE_IDLE) {
|
||||
if (snapshot) {
|
||||
if (m_web_ctrl) m_web_ctrl->Stop();
|
||||
if (m_active_media_controller)
|
||||
m_active_media_controller->Stop();
|
||||
} else {
|
||||
// http/https mode plays through the ffmpeg backend (m_media_ctrl), not
|
||||
// the webview - tear its read thread down too, otherwise it keeps
|
||||
// pulling and painting frames after the UI says "Video Stopped".
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back("<stop>");
|
||||
m_tasks.push_back({"<stop>", m_active_media_controller});
|
||||
m_cond.notify_all();
|
||||
}
|
||||
m_button_play->SetIcon("media_play");
|
||||
@@ -611,7 +607,8 @@ void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2)
|
||||
m_media_ctrl->InvalidateBestSize();
|
||||
m_button_play->SetIcon("media_play");
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back("<stop>");
|
||||
if (!webrtc_active)
|
||||
m_tasks.push_back({"<stop>", m_active_media_controller});
|
||||
m_cond.notify_all();
|
||||
if (!msg.IsEmpty())
|
||||
SetStatus(msg);
|
||||
@@ -678,7 +675,7 @@ void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2)
|
||||
|
||||
void MediaPlayCtrl::on_webrtc_status(WebRtcMediaController::Status status)
|
||||
{
|
||||
// Drop CallAfter-queued events from a superseded StartSession attempt.
|
||||
// Drop CallAfter-queued events from a superseded Play attempt.
|
||||
if (status.epoch != m_webrtc_epoch)
|
||||
return;
|
||||
if (status.kind == WebRtcMediaController::Status::Connecting) {
|
||||
@@ -839,7 +836,9 @@ void MediaPlayCtrl::jump_to_play()
|
||||
void MediaPlayCtrl::onStateChanged(wxMediaEvent &event)
|
||||
{
|
||||
auto last_state = m_last_state;
|
||||
auto state = m_media_ctrl->GetState();
|
||||
if (m_active_media_controller != m_media_ctrl)
|
||||
return;
|
||||
auto state = m_active_media_controller->GetState();
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: " << state << ", last_state: " << last_state;
|
||||
if ((int) state < 0) return;
|
||||
{
|
||||
@@ -851,14 +850,14 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent &event)
|
||||
}
|
||||
if ((last_state == MEDIASTATE_IDLE || last_state == MEDIASTATE_INITIALIZING) && state == wxMEDIASTATE_STOPPED) { return; }
|
||||
if ((last_state == wxMEDIASTATE_PAUSED || last_state == wxMEDIASTATE_PLAYING) && state == wxMEDIASTATE_STOPPED) {
|
||||
m_failed_code = m_media_ctrl->GetLastError();
|
||||
m_failed_code = m_active_media_controller->GetLastError();
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
if (last_state == MEDIASTATE_LOADING && (state == wxMEDIASTATE_STOPPED || state == wxMEDIASTATE_PAUSED)) {
|
||||
wxSize size = m_media_ctrl->GetVideoSize();
|
||||
wxSize size = m_active_media_controller->GetVideoSize();
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::onStateChanged: size: " << size.x << "x" << size.y;
|
||||
m_failed_code = m_media_ctrl->GetLastError();
|
||||
m_failed_code = m_active_media_controller->GetLastError();
|
||||
if (size.GetWidth() >= 320) {
|
||||
m_last_state = state;
|
||||
m_failed_code = 0;
|
||||
@@ -868,7 +867,7 @@ void MediaPlayCtrl::onStateChanged(wxMediaEvent &event)
|
||||
m_failed_retry = 0;
|
||||
m_disable_lan = false;
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back("<play>");
|
||||
m_tasks.push_back({"<play>", m_active_media_controller});
|
||||
m_cond.notify_all();
|
||||
} else if (event.GetId()) {
|
||||
if (m_failed_code == 0)
|
||||
@@ -923,7 +922,7 @@ void MediaPlayCtrl::load()
|
||||
m_url = m_url + "&dump_info=" + boost::lexical_cast<std::string>(dump_info_file);
|
||||
}
|
||||
boost::unique_lock lock(m_mutex);
|
||||
m_tasks.push_back(m_url);
|
||||
m_tasks.push_back({m_url, m_active_media_controller});
|
||||
m_cond.notify_all();
|
||||
}
|
||||
|
||||
@@ -943,30 +942,34 @@ void MediaPlayCtrl::media_proc()
|
||||
while (m_tasks.empty()) {
|
||||
m_cond.wait(lock);
|
||||
}
|
||||
wxString url = m_tasks.front();
|
||||
if (m_tasks.size() >= 2 && !url.IsEmpty() && url[0] != '<' && m_tasks[1] == "<stop>") {
|
||||
BOOST_LOG_TRIVIAL(trace) << "MediaPlayCtrl: busy skip url: " << url;
|
||||
MediaTask task = m_tasks.front();
|
||||
if (m_tasks.size() >= 2 && !task.command.IsEmpty() && task.command[0] != '<' &&
|
||||
m_tasks[1].command == "<stop>" && task.controller == m_tasks[1].controller) {
|
||||
BOOST_LOG_TRIVIAL(trace) << "MediaPlayCtrl: busy skip url: " << task.command;
|
||||
m_tasks.pop_front();
|
||||
m_tasks.pop_front();
|
||||
continue;
|
||||
}
|
||||
lock.unlock();
|
||||
if (url == "<stop>") {
|
||||
if (task.command == "<stop>") {
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start stop";
|
||||
m_media_ctrl->Stop();
|
||||
if (task.controller)
|
||||
task.controller->Stop();
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: end stop";
|
||||
}
|
||||
else if (url == "<exit>") {
|
||||
else if (task.command == "<exit>") {
|
||||
break;
|
||||
}
|
||||
else if (url == "<play>") {
|
||||
else if (task.command == "<play>") {
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start play";
|
||||
m_media_ctrl->Play();
|
||||
if (task.controller)
|
||||
task.controller->Play();
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: end play";
|
||||
}
|
||||
else {
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: start load";
|
||||
m_media_ctrl->Load(wxURI(url));
|
||||
if (task.controller)
|
||||
task.controller->Load(wxURI(task.command));
|
||||
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl: end load";
|
||||
}
|
||||
lock.lock();
|
||||
|
||||
@@ -75,6 +75,7 @@ private:
|
||||
static bool get_stream_url(std::string *url = nullptr);
|
||||
|
||||
CameraStreamMode current_mode() const;
|
||||
void set_active_media_controller(CameraStreamMode mode);
|
||||
|
||||
private:
|
||||
static inline const wxMediaState MEDIASTATE_IDLE = static_cast<wxMediaState>(3);
|
||||
@@ -86,10 +87,10 @@ private:
|
||||
std::shared_ptr<int> m_token = std::make_shared<int>(0);
|
||||
|
||||
wxMediaCtrl3 * m_media_ctrl;
|
||||
IMediaController * m_active_media_controller = nullptr;
|
||||
IMediaController * m_web_ctrl = nullptr;
|
||||
std::unique_ptr<WebRtcMediaController> m_webrtc_ctrl;
|
||||
CameraStreamMode m_last_mode = CameraStreamMode::none;
|
||||
bool m_webrtc_stopping = false;
|
||||
std::uint64_t m_webrtc_epoch = 0;
|
||||
std::string m_agent_camera_url;
|
||||
bool m_web_user_stopped = false;
|
||||
@@ -108,7 +109,11 @@ private:
|
||||
bool m_disable_lan = false;
|
||||
wxString m_url;
|
||||
|
||||
std::deque<wxString> m_tasks;
|
||||
struct MediaTask {
|
||||
wxString command;
|
||||
IMediaController *controller = nullptr;
|
||||
};
|
||||
std::deque<MediaTask> m_tasks;
|
||||
boost::mutex m_mutex;
|
||||
boost::condition_variable m_cond;
|
||||
boost::thread m_thread;
|
||||
|
||||
@@ -13,11 +13,13 @@ WebMediaController::WebMediaController(wxWebView* webview) : m_webview(webview)
|
||||
m_webview->SetPage("<html><head><style>html,body{margin:0;height:100%;background:#000;}</style></head><body></body></html>", "");
|
||||
}
|
||||
|
||||
void WebMediaController::Load(wxURI url) { Load(url, CameraStreamMode::http); }
|
||||
void WebMediaController::Load(wxURI url)
|
||||
{
|
||||
m_url = url.BuildURI().ToStdString();
|
||||
}
|
||||
|
||||
void WebMediaController::Load(wxURI url, CameraStreamMode mode)
|
||||
void WebMediaController::set_mode(CameraStreamMode mode)
|
||||
{
|
||||
m_url = url.BuildURI().ToStdString();
|
||||
m_stream_mode = mode;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <slic3r/GUI/IMediaController.hpp>
|
||||
#include <slic3r/Utils/IPrinterAgent.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -15,7 +16,7 @@ public:
|
||||
|
||||
void Load(wxURI url) override;
|
||||
|
||||
void Load(wxURI url, CameraStreamMode mode) override;
|
||||
void set_mode(CameraStreamMode mode);
|
||||
|
||||
void Play() override;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ WebRtcMediaController::WebRtcMediaController(std::function<void(const wxImage&,
|
||||
|
||||
WebRtcMediaController::~WebRtcMediaController()
|
||||
{
|
||||
StopSession();
|
||||
Stop();
|
||||
}
|
||||
|
||||
void WebRtcMediaController::report(Status status)
|
||||
@@ -52,8 +52,14 @@ void WebRtcMediaController::report(Status status)
|
||||
m_on_status(status);
|
||||
}
|
||||
|
||||
void WebRtcMediaController::StartSession(std::unique_ptr<ICameraSignalingChannel> channel)
|
||||
void WebRtcMediaController::set_signalling_channel(std::unique_ptr<ICameraSignalingChannel> channel)
|
||||
{
|
||||
m_pending_signaling = std::move(channel);
|
||||
}
|
||||
|
||||
void WebRtcMediaController::Play()
|
||||
{
|
||||
std::unique_ptr<ICameraSignalingChannel> channel = std::move(m_pending_signaling);
|
||||
// Tear down any previous attempt WITHOUT notifying: the Stopped that would
|
||||
// otherwise be delivered (async, via CallAfter) races the new attempt's
|
||||
// Connecting and makes the consumer cancel a session that is mid-connect.
|
||||
@@ -101,7 +107,7 @@ void WebRtcMediaController::StartSession(std::unique_ptr<ICameraSignalingChannel
|
||||
signaling->open();
|
||||
}
|
||||
|
||||
void WebRtcMediaController::StopSession()
|
||||
void WebRtcMediaController::Stop()
|
||||
{
|
||||
teardown(true);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "IMediaController.hpp"
|
||||
#include <slic3r/Utils/IPrinterAgent.hpp>
|
||||
|
||||
#include <wx/image.h>
|
||||
|
||||
@@ -36,7 +37,7 @@ public:
|
||||
DECODE_ERROR,
|
||||
TIMEOUT,
|
||||
} code = ICE_FAILED;
|
||||
// Identifies the StartSession attempt this status belongs to, so the
|
||||
// Identifies the Play attempt this status belongs to, so the
|
||||
// consumer can drop CallAfter-queued events from a superseded attempt.
|
||||
std::uint64_t epoch = 0;
|
||||
};
|
||||
@@ -45,14 +46,13 @@ public:
|
||||
std::function<void(Status)> on_status);
|
||||
~WebRtcMediaController() override;
|
||||
|
||||
void StartSession(std::unique_ptr<ICameraSignalingChannel> channel) override;
|
||||
void StopSession() override;
|
||||
void set_signalling_channel(std::unique_ptr<ICameraSignalingChannel> channel);
|
||||
std::uint64_t epoch() const { return m_epoch.load(); }
|
||||
bool is_active() const { return m_alive.load(); }
|
||||
|
||||
void Load(wxURI) override {}
|
||||
void Play() override {}
|
||||
void Stop() override { StopSession(); }
|
||||
void Play() override;
|
||||
void Stop() override;
|
||||
wxMediaState GetState() override;
|
||||
wxSize GetVideoSize() const override;
|
||||
|
||||
@@ -75,6 +75,7 @@ private:
|
||||
// addRemoteCandidate until a remote description is set, so buffer them.
|
||||
std::vector<std::pair<std::string, std::string>> m_pending_candidates;
|
||||
bool m_remote_description_set = false;
|
||||
std::unique_ptr<ICameraSignalingChannel> m_pending_signaling;
|
||||
std::unique_ptr<ICameraSignalingChannel> m_signaling;
|
||||
std::shared_ptr<rtc::PeerConnection> m_peer_connection;
|
||||
std::shared_ptr<rtc::DataChannel> m_data_channel;
|
||||
|
||||
@@ -163,13 +163,13 @@ wxMediaState wxMediaCtrl3::GetState()
|
||||
return m_state;
|
||||
}
|
||||
|
||||
int wxMediaCtrl3::GetLastError()
|
||||
int wxMediaCtrl3::GetLastError() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mutex);
|
||||
return m_error;
|
||||
}
|
||||
|
||||
wxSize wxMediaCtrl3::GetVideoSize()
|
||||
wxSize wxMediaCtrl3::GetVideoSize() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_mutex);
|
||||
return m_video_size;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "wx/bitmap.h"
|
||||
#include "wx/uri.h"
|
||||
#include "wx/mediactrl.h"
|
||||
#include "IMediaController.hpp"
|
||||
|
||||
wxDECLARE_EVENT(EVT_MEDIA_CTRL_STAT, wxCommandEvent);
|
||||
|
||||
@@ -27,18 +28,18 @@ void wxMediaCtrl_OnSize(wxWindow * ctrl, wxSize const & videoSize, int width, in
|
||||
|
||||
class AVVideoDecoder;
|
||||
|
||||
class wxMediaCtrl3 : public wxWindow, BambuLib
|
||||
class wxMediaCtrl3 : public wxWindow, public Slic3r::GUI::IMediaController, BambuLib
|
||||
{
|
||||
public:
|
||||
wxMediaCtrl3(wxWindow *parent);
|
||||
|
||||
~wxMediaCtrl3();
|
||||
~wxMediaCtrl3() override;
|
||||
|
||||
void Load(wxURI url);
|
||||
void Load(wxURI url) override;
|
||||
|
||||
void Play();
|
||||
void Play() override;
|
||||
|
||||
void Stop();
|
||||
void Stop() override;
|
||||
|
||||
// Render frames supplied by a controller which owns its own transport.
|
||||
// The frame is copied while m_mutex is held; callers may release it after
|
||||
@@ -52,11 +53,11 @@ public:
|
||||
|
||||
void SetIdleImage(wxString const & image);
|
||||
|
||||
wxMediaState GetState();
|
||||
wxMediaState GetState() override;
|
||||
|
||||
int GetLastError();
|
||||
int GetLastError() const override;
|
||||
|
||||
wxSize GetVideoSize();
|
||||
wxSize GetVideoSize() const override;
|
||||
|
||||
protected:
|
||||
DECLARE_EVENT_TABLE()
|
||||
@@ -93,7 +94,7 @@ private:
|
||||
std::uint64_t m_last_PTS{0};
|
||||
std::chrono::system_clock::time_point m_last_PTS_expected;
|
||||
std::chrono::system_clock::time_point m_last_PTS_practical;
|
||||
std::mutex m_mutex;
|
||||
mutable std::mutex m_mutex;
|
||||
std::condition_variable m_cond;
|
||||
std::thread m_thread;
|
||||
std::atomic_bool m_refresh_pending{false};
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
// Communication
|
||||
int send_message(std::string dev_id, std::string json_str, int qos, int flag) override;
|
||||
std::string default_lan_username() const override { return "bblp"; }
|
||||
int connect_printer(std::string dev_id, std::string dev_ip, std::string username, std::string password, bool use_ssl) override;
|
||||
int disconnect_printer() override;
|
||||
int send_message_to_printer(std::string dev_id, std::string json_str, int qos, int flag) override;
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include "ICameraSignalingChannel.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
@@ -109,16 +112,64 @@ public:
|
||||
virtual int command_start_camera(std::string)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
|
||||
private:
|
||||
int publish_command_json(std::string dev_id, const nlohmann::json& j, bool lan_mode)
|
||||
{
|
||||
return lan_mode ? send_message_to_printer(dev_id, j.dump(), 0, 0)
|
||||
: send_message(dev_id, j.dump(), 0, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual int command_xyz_abs(std::string dev_id, int sequence_id, bool lan_mode)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
{
|
||||
nlohmann::json j;
|
||||
j["print"]["command"] = "gcode_line";
|
||||
j["print"]["param"] = "G90 \n";
|
||||
j["print"]["sequence_id"] = std::to_string(sequence_id);
|
||||
return publish_command_json(dev_id, j, lan_mode);
|
||||
}
|
||||
virtual int command_auto_leveling(std::string dev_id, int sequence_id, bool lan_mode)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
{
|
||||
nlohmann::json j;
|
||||
j["print"]["command"] = "gcode_line";
|
||||
j["print"]["param"] = "G29 \n";
|
||||
j["print"]["sequence_id"] = std::to_string(sequence_id);
|
||||
return publish_command_json(dev_id, j, lan_mode);
|
||||
}
|
||||
virtual int command_go_home(std::string dev_id, bool is_printing, bool supports_mqtt_homing, int sequence_id, bool lan_mode)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
{
|
||||
nlohmann::json j;
|
||||
j["print"]["sequence_id"] = std::to_string(sequence_id);
|
||||
if (supports_mqtt_homing) {
|
||||
j["print"]["command"] = "back_to_center";
|
||||
} else {
|
||||
j["print"]["command"] = "gcode_line";
|
||||
j["print"]["param"] = is_printing ? "G28 X\n" : "G28 \n";
|
||||
}
|
||||
return publish_command_json(dev_id, j, lan_mode);
|
||||
}
|
||||
virtual int command_set_bed(std::string dev_id, int temp, bool supports_mqtt_bed_ctrl, int sequence_id, bool lan_mode)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
{
|
||||
nlohmann::json j;
|
||||
j["print"]["sequence_id"] = std::to_string(sequence_id);
|
||||
if (supports_mqtt_bed_ctrl) {
|
||||
j["print"]["command"] = "set_bed_temp";
|
||||
j["print"]["temp"] = temp;
|
||||
} else {
|
||||
j["print"]["command"] = "gcode_line";
|
||||
j["print"]["param"] = (boost::format("M140 S%1%\n") % temp).str();
|
||||
}
|
||||
return publish_command_json(dev_id, j, lan_mode);
|
||||
}
|
||||
virtual int command_set_nozzle(std::string dev_id, int temp, int sequence_id, bool lan_mode)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
{
|
||||
nlohmann::json j;
|
||||
j["print"]["command"] = "gcode_line";
|
||||
j["print"]["param"] = (boost::format("M104 S%1%\n") % temp).str();
|
||||
j["print"]["sequence_id"] = std::to_string(sequence_id);
|
||||
return publish_command_json(dev_id, j, lan_mode);
|
||||
}
|
||||
|
||||
virtual int command_axis_control(std::string dev_id, std::string axis, double unit, double input_val, int speed,
|
||||
bool is_core_xy, bool supports_mqtt_axis_control, int sequence_id, bool lan_mode)
|
||||
{ return ORCA_NETWORK_ERR_CMD_NOT_SUPPORTED; }
|
||||
|
||||
Reference in New Issue
Block a user