feat: generic camera stream support for http snapshot and rtsp

This commit is contained in:
Ian Chua
2026-09-01 18:02:53 +08:00
parent d486db6459
commit 0ed19d4826
28 changed files with 839 additions and 399 deletions
+109 -1
View File
@@ -146,8 +146,48 @@ MediaPlayCtrl::~MediaPlayCtrl()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": " << this;
}
void MediaPlayCtrl::SetWebMediaController(IMediaController *ctrl)
{
m_web_ctrl = ctrl;
}
CameraStreamMode MediaPlayCtrl::current_mode() const
{
auto agent = wxGetApp().getAgent();
return agent ? agent->get_camera_stream_mode() : CameraStreamMode::none;
}
void MediaPlayCtrl::SetMachineObject(MachineObject* obj)
{
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_agent_camera_url;
m_machine = machine;
m_agent_camera_url = url;
m_url = from_u8(url);
if (!changed) {
if (m_last_state == MEDIASTATE_IDLE && IsEnabled() && !m_web_user_stopped)
Play();
return;
}
m_web_user_stopped = false;
if (m_last_state != MEDIASTATE_IDLE)
Stop(" ");
if (IsEnabled())
Play();
return;
}
default:
break;
}
std::string machine = obj ? obj->get_dev_id() : "";
if (obj) {
m_camera_exists = obj->has_ipcam;
@@ -249,6 +289,42 @@ void refresh_agora_url(char const* device, char const* dev_ver, char const* chan
void MediaPlayCtrl::Play()
{
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) {
Stop(_L("Please confirm if the printer is connected."));
return;
}
if (auto agent = wxGetApp().getAgent())
agent->command_start_camera(m_machine);
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::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)
return;
if (!IsShownOnScreen())
@@ -376,8 +452,38 @@ void MediaPlayCtrl::Play()
void start_ping_test();
void MediaPlayCtrl::StopWebStream()
{
if (m_last_state == MEDIASTATE_IDLE)
return;
if (m_web_ctrl)
m_web_ctrl->Stop();
m_button_play->SetIcon("media_play");
m_last_state = MEDIASTATE_IDLE;
SetStatus(_L("Video Stopped."), false);
}
void MediaPlayCtrl::Stop(wxString const &msg, wxString const &msg2)
{
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");
m_last_state = MEDIASTATE_IDLE;
if (!msg.IsEmpty())
SetStatus(msg);
else
SetStatus(_L("Video Stopped."), false);
} else if (!msg.IsEmpty()) {
SetStatus(msg, false);
}
return;
default:
break;
}
int last_state = m_last_state;
if (m_last_state != MEDIASTATE_IDLE) {
@@ -454,10 +560,12 @@ void MediaPlayCtrl::TogglePlay()
BOOST_LOG_TRIVIAL(info) << "MediaPlayCtrl::TogglePlay";
if (m_last_state != MEDIASTATE_IDLE) {
m_next_retry = wxDateTime();
m_web_user_stopped = true;
Stop();
} else {
m_failed_retry = 0;
m_user_triggered = true;
m_web_user_stopped = false;
if (m_last_user_play + wxTimeSpan::Minutes(5) < wxDateTime::Now()) {
m_last_failed_codes.clear();
m_last_user_play = wxDateTime::Now();
@@ -661,7 +769,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;