/*************************************************************************************** * * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. * * By downloading, copying, installing or using the software you agree to this license. * If you do not agree to this license, do not download, install, * copy or use the software. * * Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved. * * Redistribution and use in binary forms, with or without modification, are permitted. * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific * language governing permissions and limitations under the License. * ****************************************************************************************/ #include "http_mjpeg_player.h" #include "utils.h" /***************************************************************************************/ int http_mjpeg_notify_callback(int evt, void * puser) { CHttpMjpegPlayer * pPlayer = (CHttpMjpegPlayer *) puser; pPlayer->onNotify(evt); return 0; } int http_mjpeg_video_callback(uint8 * pdata, int len, void *puser) { CHttpMjpegPlayer * pPlayer = (CHttpMjpegPlayer *) puser; pPlayer->onVideo(pdata, len, 0); return 0; } /***************************************************************************************/ CHttpMjpegPlayer::CHttpMjpegPlayer(): CVideoPlayer() { memset(m_ip, 0, sizeof(m_ip)); } CHttpMjpegPlayer::~CHttpMjpegPlayer() { close(); } std::string CHttpMjpegPlayer::createNewMJPEGUrl(const std::string& username, const std::string& password, const std::string& url) { // Copy the original strings to avoid modifying the originals std::string modUsername = username; std::string modPassword = password; // Replace '@' with '_' in username and password std::replace(modUsername.begin(), modUsername.end(), '@', '_'); std::replace(modPassword.begin(), modPassword.end(), '@', '_'); // Extract the protocol and rest of the URL size_t protocolEndPos = url.find("://") + 3; // Find the position right after "://" std::string protocol = url.substr(0, protocolEndPos); // Include "://" // Construct the new URL with modified credentials std::string newUrl = protocol; newUrl += modUsername + ":" + modPassword + "@"; newUrl += url.substr(protocolEndPos); return newUrl; } BOOL CHttpMjpegPlayer::open(std::string fileName) { close(); CVideoPlayer::open(fileName); char host[100]; url_split(fileName.c_str(), NULL, 0, NULL, 0, NULL, 0, host, sizeof(host), NULL, NULL, 0); if (host[0] == '\0') { return FALSE; } strncpy(m_ip, host, sizeof(m_ip) - 1); m_httpmjpeg.set_notify_cb(http_mjpeg_notify_callback, this); m_httpmjpeg.set_video_cb(http_mjpeg_video_callback); return TRUE; } BOOL CHttpMjpegPlayer::open(std::string _username, std::string _password, std::string _url) { close(); CVideoPlayer::open(_username, _password, _url); char host[100]; std::string fileName = createNewMJPEGUrl(_username, _password, _url); url_split(fileName.c_str(), NULL, 0, NULL, 0, NULL, 0, host, sizeof(host), NULL, NULL, 0); if (host[0] == '\0') { return FALSE; } strncpy(m_ip, host, sizeof(m_ip) - 1); m_httpmjpeg.set_notify_cb(http_mjpeg_notify_callback, this); m_httpmjpeg.set_video_cb(http_mjpeg_video_callback); return TRUE; } void CHttpMjpegPlayer::close() { // stop http-mjpeg connection m_httpmjpeg.mjpeg_stop(); m_httpmjpeg.mjpeg_close(); m_bPlaying = FALSE; m_bPaused = FALSE; CVideoPlayer::StopVideoDecoder(); CVideoPlayer::close(); } void CHttpMjpegPlayer::setBbox(cv::Rect bbox) { CVideoPlayer::setBbox(bbox); } void CHttpMjpegPlayer::setCrop(bool crop) { CVideoPlayer::setCrop(crop); } BOOL CHttpMjpegPlayer::play() { if (m_httpmjpeg.mjpeg_start(m_sFileName.c_str(), m_acct.c_str(), m_pass.c_str())) { m_bPlaying = TRUE; m_bPaused = FALSE; } CVideoPlayer::StartVideoDecoder();// Start the video decoder return m_bPlaying; } void CHttpMjpegPlayer::stop() { if (m_bPlaying || m_bPaused) { m_httpmjpeg.mjpeg_stop(); } // Set flags BEFORE stopping decoder so rx thread stops calling decode() m_bPlaying = FALSE; m_bPaused = FALSE; CVideoPlayer::StopVideoDecoder(); // Stop the video decoder } BOOL CHttpMjpegPlayer::pause() { CVideoPlayer::StopVideoDecoder(); // Stop the video decoder return m_bPaused; } BOOL CHttpMjpegPlayer::seek(int pos) { return FALSE; } int CHttpMjpegPlayer::getVideoCodec() { return VIDEO_CODEC_JPEG; } void CHttpMjpegPlayer::onNotify(int evt) { if (evt == MJPEG_EVE_CONNSUCC) { openVideo(VIDEO_CODEC_JPEG); } } void CHttpMjpegPlayer::onVideo(uint8 * pdata, int len, uint32 ts) { playVideo(pdata, len, ts, 0); } BOOL CHttpMjpegPlayer::onRecord() { avi_set_video_info(m_pAviCtx, 0, 0, 0, "JPEG"); avi_update_header(m_pAviCtx); return TRUE; }