Working on video

This commit is contained in:
ganome 2025-12-05 11:54:26 -07:00
parent e86abb53d6
commit 252d462309
Signed by untrusted user who does not match committer: Ganome
GPG Key ID: 944DE53336D81B83
4 changed files with 87 additions and 10 deletions

View File

@ -106,8 +106,10 @@ chat_client_qt_autogen/timestamp: \
/usr/include/locale.h \ /usr/include/locale.h \
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt5/Gentoo/gentoo-qconfig.h \ /usr/include/qt5/Gentoo/gentoo-qconfig.h \
/usr/include/qt5/QtCore/QDataStream \
/usr/include/qt5/QtCore/QFlags \ /usr/include/qt5/QtCore/QFlags \
/usr/include/qt5/QtCore/QThread \ /usr/include/qt5/QtCore/QThread \
/usr/include/qt5/QtCore/QTime \
/usr/include/qt5/QtCore/QTimer \ /usr/include/qt5/QtCore/QTimer \
/usr/include/qt5/QtCore/qabstractitemmodel.h \ /usr/include/qt5/QtCore/qabstractitemmodel.h \
/usr/include/qt5/QtCore/qalgorithms.h \ /usr/include/qt5/QtCore/qalgorithms.h \
@ -187,6 +189,7 @@ chat_client_qt_autogen/timestamp: \
/usr/include/qt5/QtCore/qvector.h \ /usr/include/qt5/QtCore/qvector.h \
/usr/include/qt5/QtCore/qversiontagging.h \ /usr/include/qt5/QtCore/qversiontagging.h \
/usr/include/qt5/QtGui/QImage \ /usr/include/qt5/QtGui/QImage \
/usr/include/qt5/QtGui/QPainter \
/usr/include/qt5/QtGui/QPixmap \ /usr/include/qt5/QtGui/QPixmap \
/usr/include/qt5/QtGui/qbrush.h \ /usr/include/qt5/QtGui/qbrush.h \
/usr/include/qt5/QtGui/qcolor.h \ /usr/include/qt5/QtGui/qcolor.h \
@ -201,6 +204,7 @@ chat_client_qt_autogen/timestamp: \
/usr/include/qt5/QtGui/qkeysequence.h \ /usr/include/qt5/QtGui/qkeysequence.h \
/usr/include/qt5/QtGui/qmatrix.h \ /usr/include/qt5/QtGui/qmatrix.h \
/usr/include/qt5/QtGui/qpaintdevice.h \ /usr/include/qt5/QtGui/qpaintdevice.h \
/usr/include/qt5/QtGui/qpainter.h \
/usr/include/qt5/QtGui/qpalette.h \ /usr/include/qt5/QtGui/qpalette.h \
/usr/include/qt5/QtGui/qpen.h \ /usr/include/qt5/QtGui/qpen.h \
/usr/include/qt5/QtGui/qpixelformat.h \ /usr/include/qt5/QtGui/qpixelformat.h \

View File

@ -102,8 +102,10 @@
/usr/include/locale.h \ /usr/include/locale.h \
/usr/include/pthread.h \ /usr/include/pthread.h \
/usr/include/qt5/Gentoo/gentoo-qconfig.h \ /usr/include/qt5/Gentoo/gentoo-qconfig.h \
/usr/include/qt5/QtCore/QDataStream \
/usr/include/qt5/QtCore/QFlags \ /usr/include/qt5/QtCore/QFlags \
/usr/include/qt5/QtCore/QThread \ /usr/include/qt5/QtCore/QThread \
/usr/include/qt5/QtCore/QTime \
/usr/include/qt5/QtCore/QTimer \ /usr/include/qt5/QtCore/QTimer \
/usr/include/qt5/QtCore/qabstractitemmodel.h \ /usr/include/qt5/QtCore/qabstractitemmodel.h \
/usr/include/qt5/QtCore/qalgorithms.h \ /usr/include/qt5/QtCore/qalgorithms.h \
@ -183,6 +185,7 @@
/usr/include/qt5/QtCore/qvector.h \ /usr/include/qt5/QtCore/qvector.h \
/usr/include/qt5/QtCore/qversiontagging.h \ /usr/include/qt5/QtCore/qversiontagging.h \
/usr/include/qt5/QtGui/QImage \ /usr/include/qt5/QtGui/QImage \
/usr/include/qt5/QtGui/QPainter \
/usr/include/qt5/QtGui/QPixmap \ /usr/include/qt5/QtGui/QPixmap \
/usr/include/qt5/QtGui/qbrush.h \ /usr/include/qt5/QtGui/qbrush.h \
/usr/include/qt5/QtGui/qcolor.h \ /usr/include/qt5/QtGui/qcolor.h \
@ -197,6 +200,7 @@
/usr/include/qt5/QtGui/qkeysequence.h \ /usr/include/qt5/QtGui/qkeysequence.h \
/usr/include/qt5/QtGui/qmatrix.h \ /usr/include/qt5/QtGui/qmatrix.h \
/usr/include/qt5/QtGui/qpaintdevice.h \ /usr/include/qt5/QtGui/qpaintdevice.h \
/usr/include/qt5/QtGui/qpainter.h \
/usr/include/qt5/QtGui/qpalette.h \ /usr/include/qt5/QtGui/qpalette.h \
/usr/include/qt5/QtGui/qpen.h \ /usr/include/qt5/QtGui/qpen.h \
/usr/include/qt5/QtGui/qpixelformat.h \ /usr/include/qt5/QtGui/qpixelformat.h \

View File

@ -25,6 +25,9 @@
#include <QPixmap> #include <QPixmap>
#include <QTimer> #include <QTimer>
#include <QDialog> #include <QDialog>
#include <QPainter>
#include <QDataStream>
#include <QTime>
#include <iostream> #include <iostream>
#include <mutex> #include <mutex>
#include <map> #include <map>
@ -171,7 +174,7 @@ class ChatClient : public QMainWindow {
Q_OBJECT Q_OBJECT
public: public:
ChatClient(QWidget *parent = nullptr) : QMainWindow(parent), m_camera(nullptr), m_authenticated(false) { ChatClient(QWidget *parent = nullptr) : QMainWindow(parent), m_camera(nullptr), m_camera_timer(nullptr), m_authenticated(false) {
setWindowTitle("SCAR Chat Client"); setWindowTitle("SCAR Chat Client");
setGeometry(100, 100, 1000, 700); setGeometry(100, 100, 1000, 700);
@ -308,6 +311,10 @@ public:
} }
~ChatClient() { ~ChatClient() {
if (m_camera_timer) {
m_camera_timer->stop();
delete m_camera_timer;
}
if (m_camera) { if (m_camera) {
m_camera->stop(); m_camera->stop();
delete m_camera; delete m_camera;
@ -421,8 +428,44 @@ private slots:
try { try {
m_camera->start(); m_camera->start();
chat_display->append("[System] Camera enabled: " + camera_info_label->text()); chat_display->append("[System] Camera enabled: " + camera_info_label->text());
local_video_label->setText("Camera Active\n(Video capture enabled)"); local_video_label->setText("Camera Active");
local_video_label->setStyleSheet("border: 2px solid green; background-color: #1a1a1a; color: white;"); local_video_label->setStyleSheet("border: 2px solid green; background-color: #1a1a1a;");
// Start camera preview timer
if (!m_camera_timer) {
m_camera_timer = new QTimer(this);
connect(m_camera_timer, &QTimer::timeout, this, [this]() {
// Create a test video frame showing camera is active
QPixmap pixmap(640, 480);
pixmap.fill(Qt::black);
// Draw a simple pattern to show camera is working
QPainter painter(&pixmap);
painter.fillRect(pixmap.rect(), QColor(30, 30, 30));
painter.setPen(QPen(Qt::green, 2));
painter.drawRect(10, 10, pixmap.width()-20, pixmap.height()-20);
painter.setPen(QPen(Qt::white));
painter.setFont(QFont("Arial", 16));
painter.drawText(pixmap.rect(), Qt::AlignCenter,
QString("Camera: %1\n[%2]").arg(camera_info_label->text()).arg(
QTime::currentTime().toString("hh:mm:ss")));
painter.end();
local_video_label->setPixmap(pixmap);
// Send frame data to server
if (socket && socket->state() == QSslSocket::ConnectedState) {
// Encode pixmap as base64 and send as VIDEO_FRAME message
QByteArray buffer;
QDataStream stream(&buffer, QIODevice::WriteOnly);
stream << pixmap.toImage();
QString frame_data = QString::fromUtf8(buffer.toBase64());
QString msg = QString("VIDEO_FRAME:%1\n").arg(frame_data);
socket->write(msg.toUtf8());
}
});
m_camera_timer->start(100); // 10 FPS for video frames
}
if (socket->state() == QSslSocket::ConnectedState) { if (socket->state() == QSslSocket::ConnectedState) {
socket->write("CAMERA_ENABLE\n"); socket->write("CAMERA_ENABLE\n");
@ -437,9 +480,12 @@ private slots:
if (m_camera) { if (m_camera) {
m_camera->stop(); m_camera->stop();
} }
if (m_camera_timer) {
m_camera_timer->stop();
}
chat_display->append("[System] Camera disabled"); chat_display->append("[System] Camera disabled");
local_video_label->setText("Camera Disabled\nClick 'Enable Camera' to start"); local_video_label->setText("Camera Disabled");
local_video_label->setStyleSheet("border: 2px solid gray; background-color: black; color: white;"); local_video_label->setStyleSheet("border: 2px solid gray; background-color: black;");
if (socket->state() == QSslSocket::ConnectedState) { if (socket->state() == QSslSocket::ConnectedState) {
socket->write("CAMERA_DISABLE\n"); socket->write("CAMERA_DISABLE\n");
@ -510,7 +556,27 @@ private slots:
add_remote_user(username, false); add_remote_user(username, false);
chat_display->append("[System] " + username + " disabled their camera"); chat_display->append("[System] " + username + " disabled their camera");
} else if (message.startsWith("VIDEO_FRAME:")) { } else if (message.startsWith("VIDEO_FRAME:")) {
// Placeholder for future video frame implementation // Parse video frame message: VIDEO_FRAME:username:data
int second_colon = message.indexOf(':', 12);
if (second_colon > 12) {
QString username = message.mid(12, second_colon - 12);
QString frame_data = message.mid(second_colon + 1);
// Decode base64 image data
QByteArray buffer = QByteArray::fromBase64(frame_data.toUtf8());
if (!buffer.isEmpty()) {
QDataStream stream(&buffer, QIODevice::ReadOnly);
QImage image;
stream >> image;
if (!image.isNull()) {
QPixmap pixmap = QPixmap::fromImage(image);
if (remote_users.find(username) != remote_users.end()) {
remote_users[username]->update_video_frame(pixmap);
}
}
}
}
} else { } else {
// Regular chat message // Regular chat message
chat_display->append(message); chat_display->append(message);
@ -612,6 +678,7 @@ private:
// Camera // Camera
QCamera *m_camera; QCamera *m_camera;
QTimer *m_camera_timer;
// Connection // Connection
QSslSocket *socket; QSslSocket *socket;

View File

@ -159,13 +159,15 @@ void handle_client(SSL *ssl, int client_socket) {
// Handle camera status messages // Handle camera status messages
if (msg_str.find("CAMERA_ENABLE") != std::string::npos) { if (msg_str.find("CAMERA_ENABLE") != std::string::npos) {
std::cout << "User " << nickname << " enabled camera" << std::endl; std::cout << "User " << nickname << " enabled camera" << std::endl;
std::string timestamp = get_timestamp(); std::string broadcast_msg = "USER_CAMERA_ON:" + nickname + "\n";
std::string broadcast_msg = "*{" + timestamp + "}* " + nickname + ": Camera Enabled\n";
broadcast_message(broadcast_msg, ssl); broadcast_message(broadcast_msg, ssl);
} else if (msg_str.find("CAMERA_DISABLE") != std::string::npos) { } else if (msg_str.find("CAMERA_DISABLE") != std::string::npos) {
std::cout << "User " << nickname << " disabled camera" << std::endl; std::cout << "User " << nickname << " disabled camera" << std::endl;
std::string timestamp = get_timestamp(); std::string broadcast_msg = "USER_CAMERA_OFF:" + nickname + "\n";
std::string broadcast_msg = "*{" + timestamp + "}* " + nickname + ": Camera Disabled\n"; broadcast_message(broadcast_msg, ssl);
} else if (msg_str.find("VIDEO_FRAME:") != std::string::npos) {
// Forward video frames with username prefix
std::string broadcast_msg = "VIDEO_FRAME:" + nickname + ":" + msg_str.substr(12) + "\n";
broadcast_message(broadcast_msg, ssl); broadcast_message(broadcast_msg, ssl);
} else { } else {
// Regular chat message - format with timestamp and nickname // Regular chat message - format with timestamp and nickname