diff --git a/src/slic3r/GUI/MediaPlayCtrl.cpp b/src/slic3r/GUI/MediaPlayCtrl.cpp index 05c89f122f..825f7071d7 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.cpp +++ b/src/slic3r/GUI/MediaPlayCtrl.cpp @@ -155,23 +155,20 @@ CameraStreamMode MediaPlayCtrl::current_mode() const return agent ? agent->get_camera_stream_mode() : CameraStreamMode::none; } -bool MediaPlayCtrl::is_web_stream_mode() const -{ - const CameraStreamMode mode = current_mode(); - return mode == CameraStreamMode::http || mode == CameraStreamMode::http_snapshot; -} - void MediaPlayCtrl::SetMachineObject(MachineObject* obj) { - if (is_web_stream_mode()) { + switch (current_mode()) { + case CameraStreamMode::http: + case CameraStreamMode::http_snapshot: + case CameraStreamMode::rtsp: { std::string machine = obj ? obj->get_dev_id() : ""; 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_http_url; + bool changed = machine != m_machine || url != m_agent_camera_url; m_machine = machine; - m_http_url = url; + m_agent_camera_url = url; m_url = from_u8(url); if (!changed) { if (m_last_state == MEDIASTATE_IDLE && IsEnabled() && !m_web_user_stopped) @@ -185,6 +182,9 @@ void MediaPlayCtrl::SetMachineObject(MachineObject* obj) Play(); return; } + default: + break; + } std::string machine = obj ? obj->get_dev_id() : ""; if (obj) { @@ -294,7 +294,11 @@ void refresh_agora_url(char const* device, char const* dev_ver, char const* chan void MediaPlayCtrl::Play() { - if (is_web_stream_mode()) { + switch (current_mode()) { + case CameraStreamMode::http: + case CameraStreamMode::http_snapshot: + if (!m_next_retry.IsValid() || wxDateTime::Now() < m_next_retry) + 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) { @@ -309,6 +313,21 @@ void MediaPlayCtrl::Play() m_last_state = wxMEDIASTATE_PLAYING; SetStatus(_L("Playing..."), false); return; + case CameraStreamMode::rtsp: + 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() || !IsEnabled() || !m_camera_exists || m_url.IsEmpty()) { + Stop(_L("Please confirm if the printer is connected.")); + return; + } + m_button_play->SetIcon("media_stop"); + load(); + return; + default: + break; } if (!m_next_retry.IsValid() || wxDateTime::Now() < m_next_retry) @@ -451,7 +470,9 @@ void MediaPlayCtrl::StopWebStream() void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2) { - if (is_web_stream_mode()) { + switch (current_mode()) { + case CameraStreamMode::http: + case CameraStreamMode::http_snapshot: if (m_last_state != MEDIASTATE_IDLE) { if (m_web_ctrl) m_web_ctrl->Stop(); m_button_play->SetIcon("media_play"); @@ -464,6 +485,8 @@ void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2) SetStatus(msg, false); } return; + default: + break; } int last_state = m_last_state; @@ -751,7 +774,7 @@ void MediaPlayCtrl::load() { m_last_state = MEDIASTATE_LOADING; SetStatus(_L("Loading...")); - if (wxGetApp().app_config->get("internal_developer_mode") == "true") { + if (current_mode() != CameraStreamMode::rtsp) { std::string file_h264 = data_dir() + "/video.h264"; std::string file_info = data_dir() + "/video.info"; BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl dump video to " << file_h264; diff --git a/src/slic3r/GUI/MediaPlayCtrl.h b/src/slic3r/GUI/MediaPlayCtrl.h index 3f091b1027..66bf6487c6 100644 --- a/src/slic3r/GUI/MediaPlayCtrl.h +++ b/src/slic3r/GUI/MediaPlayCtrl.h @@ -73,7 +73,6 @@ private: static bool get_stream_url(std::string *url = nullptr); CameraStreamMode current_mode() const; - bool is_web_stream_mode() const; private: static inline const wxMediaState MEDIASTATE_IDLE = static_cast(3); @@ -86,7 +85,7 @@ private: wxMediaCtrl2 * m_media_ctrl; IMediaController * m_web_ctrl = nullptr; - std::string m_http_url; + std::string m_agent_camera_url; bool m_web_user_stopped = false; wxMediaState m_last_state = MEDIASTATE_IDLE; std::string m_machine; diff --git a/src/slic3r/GUI/WebMediaController.cpp b/src/slic3r/GUI/WebMediaController.cpp index 1c234c1fe2..13d820c98f 100644 --- a/src/slic3r/GUI/WebMediaController.cpp +++ b/src/slic3r/GUI/WebMediaController.cpp @@ -4,7 +4,16 @@ namespace Slic3r { namespace GUI { -WebMediaController::WebMediaController(wxWebView *webview) : m_webview(webview) {} +WebMediaController::WebMediaController(wxWebView *webview) : m_webview(webview) +{ + if (!m_webview) + return; + + m_webview->SetBackgroundColour(*wxBLACK); + m_webview->SetPage( + "", + ""); +} void WebMediaController::Load(wxURI url) { diff --git a/src/slic3r/GUI/wxMediaCtrl2.cpp b/src/slic3r/GUI/wxMediaCtrl2.cpp index f2d1d2701e..957efefd3b 100644 --- a/src/slic3r/GUI/wxMediaCtrl2.cpp +++ b/src/slic3r/GUI/wxMediaCtrl2.cpp @@ -322,6 +322,9 @@ void wxMediaCtrl2::PostGtkSinkStateEvent(int id) void wxMediaCtrl2::Load(wxURI url) { + const wxString scheme = url.GetScheme(); + const bool generic_rtsp = scheme.CmpNoCase("rtsp") == 0 || scheme.CmpNoCase("rtsps") == 0; + #ifdef __WIN32__ InvalidateBestSize(); if (m_imp == nullptr) { @@ -342,7 +345,9 @@ void wxMediaCtrl2::Load(wxURI url) wxPostEvent(this, event); return; } - { + // BambuSource handles the proprietary bambu:// transport. Generic RTSP + // streams must go directly to the native Windows media backend. + if (!generic_rtsp) { wxRegKey key11(wxRegKey::HKCU, L"SOFTWARE\\Classes\\CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); wxRegKey key12(wxRegKey::HKCR, L"CLSID\\" CLSID_BAMBU_SOURCE L"\\InProcServer32"); wxString path = key11.Exists() ? key11.QueryDefaultValue() @@ -422,8 +427,10 @@ void wxMediaCtrl2::Load(wxURI url) keyWmp.SetValue("Permissions", permissions); } } - url = wxURI(url.BuildURI().append("&hwnd=").append(boost::lexical_cast(GetHandle())).append("&tid=").append( - boost::lexical_cast(GetCurrentThreadId()))); + if (!generic_rtsp) { + url = wxURI(url.BuildURI().append("&hwnd=").append(boost::lexical_cast(GetHandle())).append("&tid=").append( + boost::lexical_cast(GetCurrentThreadId()))); + } #endif #ifdef __WXGTK3__ GstElementFactory *factory; @@ -458,7 +465,10 @@ void wxMediaCtrl2::Load(wxURI url) gst_object_unref(factory); } - if (!hasplugins) { + // Generic RTSP streams may use codecs other than H.264; let GStreamer + // select the decoder from the stream caps instead of applying the Bambu + // liveview H.264 preflight. + if (!generic_rtsp && !hasplugins) { CallAfter([] { wxMessageBox(_L("Your system is missing H.264 codecs for GStreamer, which are required to play video. (Try installing the gstreamer1.0-plugins-bad or gstreamer1.0-libav packages, then restart Orca Slicer?)"), _L("Error"), wxOK); }); @@ -473,6 +483,10 @@ void wxMediaCtrl2::Load(wxURI url) #endif m_error = 0; m_loaded = false; +#ifdef __LINUX__ + if (generic_rtsp) + gst_bambu_last_error = 0; +#endif #if defined(__LINUX__) && defined(__WXGTK__) if (m_use_gtk_sink && m_gtk_playbin) { const std::string uri = std::string(url.BuildURI().ToUTF8().data()); diff --git a/src/slic3r/Utils/SnapmakerPrinterAgent.hpp b/src/slic3r/Utils/SnapmakerPrinterAgent.hpp index be0eeaece9..a92209a513 100644 --- a/src/slic3r/Utils/SnapmakerPrinterAgent.hpp +++ b/src/slic3r/Utils/SnapmakerPrinterAgent.hpp @@ -22,8 +22,10 @@ public: int command_start_camera(std::string dev_id) override; FilamentSyncMode get_filament_sync_mode() const override { return FilamentSyncMode::subscription; } - CameraStreamMode get_camera_stream_mode() const override { return CameraStreamMode::http_snapshot; } - std::string get_camera_url() const override { return device_info.base_url + "/server/files/camera/monitor.jpg"; } + // CameraStreamMode get_camera_stream_mode() const override { return CameraStreamMode::http_snapshot; } + CameraStreamMode get_camera_stream_mode() const override { return CameraStreamMode::rtsp; } + // std::string get_camera_url() const override { return device_info.base_url + "/server/files/camera/monitor.jpg"; } + std::string get_camera_url() const override { return "rtsp://100.99.196.114:8554/stream"; } private: // Combine filament_type + filament_sub_type into a unified type string