mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-08 16:59:59 +01:00
Managing client name and disconnection (e.g. end vimix)
This commit is contained in:
@@ -183,11 +183,11 @@ void Connection::ask()
|
||||
// erase connection if its life score is negative (not responding too many times)
|
||||
if ( it!=Connection::manager().connections_.begin() && (*it).alive < 0 ) {
|
||||
// inform streamer to cancel streaming to this client
|
||||
Streaming::manager().removeStreams( (*it).address );
|
||||
Streaming::manager().removeStreams( (*it).name );
|
||||
// remove from list
|
||||
it = Connection::manager().connections_.erase(it);
|
||||
#ifdef CONNECTION_DEBUG
|
||||
Log::Info("A connection was lost");
|
||||
Log::Info("List of connection updated:");
|
||||
Connection::manager().print();
|
||||
#endif
|
||||
}
|
||||
@@ -254,7 +254,7 @@ void ConnectionRequestListener::ProcessMessage( const osc::ReceivedMessage& m,
|
||||
// a new connection! Add to list
|
||||
Connection::manager().connections_.push_back(info);
|
||||
#ifdef CONNECTION_DEBUG
|
||||
Log::Info("New connection added");
|
||||
Log::Info("List of connection updated:");
|
||||
Connection::manager().print();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -544,5 +544,14 @@ void ImGuiVisitor::visit (NetworkSource& s)
|
||||
ImGui::Text(" - %s (%dx%d)\n - Network host %s:%d", NetworkToolkit::protocol_name[ns->protocol()],
|
||||
ns->resolution().x, ns->resolution().y, ns->IP().c_str(), ns->port());
|
||||
|
||||
if ( !ns->isPlaying()) {
|
||||
|
||||
if ( ImGui::Button("Interrupted - Reload", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
|
||||
{
|
||||
// TODO : reload ?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ void NetworkStream::open(const std::string &nameconnection)
|
||||
p << osc::BeginMessage( OSC_PREFIX OSC_STREAM_REQUEST );
|
||||
// send my listening port to indicate to Connection::manager where to reply
|
||||
p << listener_port_;
|
||||
p << Connection::manager().info().name.c_str();
|
||||
p << osc::EndMessage;
|
||||
|
||||
// send OSC message to streamer
|
||||
|
||||
@@ -33,16 +33,18 @@ typedef enum {
|
||||
|
||||
struct StreamConfig {
|
||||
|
||||
Protocol protocol;
|
||||
std::string client_name;
|
||||
std::string client_address;
|
||||
int port;
|
||||
Protocol protocol;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
StreamConfig () {
|
||||
protocol = DEFAULT;
|
||||
client_name = "";
|
||||
client_address = "127.0.0.1";
|
||||
port = 0;
|
||||
protocol = DEFAULT;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
@@ -50,6 +52,7 @@ struct StreamConfig {
|
||||
inline StreamConfig& operator = (const StreamConfig& o)
|
||||
{
|
||||
if (this != &o) {
|
||||
this->client_name = o.client_name;
|
||||
this->client_address = o.client_address;
|
||||
this->port = o.port;
|
||||
this->protocol = o.protocol;
|
||||
|
||||
@@ -658,7 +658,8 @@ GstFlowReturn Stream::callback_new_sample (GstAppSink *sink, gpointer p)
|
||||
{
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
// Log::Info("callback_new_sample");
|
||||
// if (gst_app_sink_is_eos (sink))
|
||||
// Log::Info("callback_new_sample got EOS");
|
||||
|
||||
// non-blocking read new sample
|
||||
GstSample *sample = gst_app_sink_pull_sample(sink);
|
||||
|
||||
59
Streamer.cpp
59
Streamer.cpp
@@ -1,4 +1,5 @@
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
|
||||
// Desktop OpenGL function loader
|
||||
#include <glad/glad.h>
|
||||
@@ -46,7 +47,8 @@ void StreamingRequestListener::ProcessMessage( const osc::ReceivedMessage& m,
|
||||
|
||||
osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
|
||||
int reply_to_port = (arg++)->AsInt32();
|
||||
Streaming::manager().addStream(sender, reply_to_port);
|
||||
const char *client_name = (arg++)->AsString();
|
||||
Streaming::manager().addStream(sender, reply_to_port, client_name);
|
||||
|
||||
#ifdef STREAMER_DEBUG
|
||||
Log::Info("%s wants a stream.", sender);
|
||||
@@ -78,6 +80,30 @@ Streaming::Streaming() : session_(nullptr), width_(0), height_(0)
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Streaming::busy() const
|
||||
{
|
||||
bool b = false;
|
||||
|
||||
std::vector<VideoStreamer *>::const_iterator sit = streamers_.begin();
|
||||
for (; sit != streamers_.end() && !b; sit++)
|
||||
b = (*sit)->busy() ;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> Streaming::listStreams() const
|
||||
{
|
||||
std::vector<std::string> ls;
|
||||
|
||||
std::vector<VideoStreamer *>::const_iterator sit = streamers_.begin();
|
||||
for (; sit != streamers_.end(); sit++)
|
||||
ls.push_back( (*sit)->info() );
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
void wait_for_request_(UdpListeningReceiveSocket *receiver)
|
||||
{
|
||||
receiver->Run();
|
||||
@@ -92,7 +118,7 @@ void Streaming::enable(bool on)
|
||||
else {
|
||||
// end streaming requests
|
||||
receiver_->AsynchronousBreak();
|
||||
// end all streaming
|
||||
// ending and removing all streaming
|
||||
for (auto sit = streamers_.begin(); sit != streamers_.end(); sit=streamers_.erase(sit))
|
||||
(*sit)->stop();
|
||||
Log::Info("Refusing stream requests to %s. No streaming ongoing.", Connection::manager().info().name.c_str());
|
||||
@@ -137,13 +163,13 @@ void Streaming::removeStream(const std::string &sender, int port)
|
||||
|
||||
}
|
||||
|
||||
void Streaming::removeStreams(const std::string &ip)
|
||||
void Streaming::removeStreams(const std::string &clientname)
|
||||
{
|
||||
// remove all streamers matching given IP
|
||||
std::vector<VideoStreamer *>::const_iterator sit = streamers_.begin();
|
||||
while ( sit != streamers_.end() ){
|
||||
NetworkToolkit::StreamConfig config = (*sit)->config_;
|
||||
if (config.client_address.compare(ip) == 0) {
|
||||
if (config.client_name.compare(clientname) == 0) {
|
||||
#ifdef STREAMER_DEBUG
|
||||
Log::Info("Ending streaming to %s:%d", config.client_address.c_str(), config.port);
|
||||
#endif
|
||||
@@ -158,7 +184,7 @@ void Streaming::removeStreams(const std::string &ip)
|
||||
}
|
||||
|
||||
|
||||
void Streaming::addStream(const std::string &sender, int reply_to)
|
||||
void Streaming::addStream(const std::string &sender, int reply_to, const std::string &clientname)
|
||||
{
|
||||
// get ip of client
|
||||
std::string sender_ip = sender.substr(0, sender.find_last_of(":"));
|
||||
@@ -172,6 +198,7 @@ void Streaming::addStream(const std::string &sender, int reply_to)
|
||||
// prepare an offer
|
||||
NetworkToolkit::StreamConfig conf;
|
||||
conf.client_address = sender_ip;
|
||||
conf.client_name = clientname;
|
||||
conf.port = std::stoi(sender_port); // this port seems free, so re-use it!
|
||||
conf.width = width_;
|
||||
conf.height = height_;
|
||||
@@ -183,7 +210,7 @@ void Streaming::addStream(const std::string &sender, int reply_to)
|
||||
else {
|
||||
conf.protocol = NetworkToolkit::UDP_JPEG;
|
||||
}
|
||||
// conf.protocol = NetworkToolkit::UDP_JPEG;
|
||||
// conf.protocol = NetworkToolkit::UDP_JPEG; // force udp for testing
|
||||
|
||||
// build OSC message
|
||||
char buffer[IP_MTU_SIZE];
|
||||
@@ -347,8 +374,8 @@ void VideoStreamer::addFrame (FrameBuffer *frame_buffer, float dt)
|
||||
}
|
||||
|
||||
// all good
|
||||
Log::Info("Streaming video to %s:%d (%d x %d)",
|
||||
config_.client_address.c_str(), config_.port, width_, height_);
|
||||
Log::Info("Streaming video to %s (%d x %d)",
|
||||
config_.client_name.c_str(), width_, height_);
|
||||
|
||||
// start streaming !!
|
||||
streaming_ = true;
|
||||
@@ -463,6 +490,9 @@ void VideoStreamer::addFrame (FrameBuffer *frame_buffer, float dt)
|
||||
// finished !
|
||||
else {
|
||||
|
||||
// send EOS
|
||||
gst_app_src_end_of_stream (src_);
|
||||
|
||||
// make sure the shared memory socket is deleted
|
||||
if (config_.protocol == NetworkToolkit::SHM_RAW) {
|
||||
std::string path = SystemToolkit::full_filename(SystemToolkit::settings_path(), "shm");
|
||||
@@ -470,7 +500,7 @@ void VideoStreamer::addFrame (FrameBuffer *frame_buffer, float dt)
|
||||
SystemToolkit::remove_file(path);
|
||||
}
|
||||
|
||||
Log::Notify("Streaming to %s:%d finished after %s s.", config_.client_address.c_str(), config_.port,
|
||||
Log::Notify("Streaming to %s finished after %s s.", config_.client_name.c_str(),
|
||||
GstToolkit::time_to_string(timestamp_).c_str());
|
||||
|
||||
}
|
||||
@@ -488,12 +518,15 @@ void VideoStreamer::stop ()
|
||||
|
||||
std::string VideoStreamer::info()
|
||||
{
|
||||
std::string ret = "Streaming terminated.";
|
||||
std::ostringstream ret;
|
||||
if (streaming_) {
|
||||
ret = "Streaming ";
|
||||
ret += NetworkToolkit::protocol_name[config_.protocol];
|
||||
ret << NetworkToolkit::protocol_name[config_.protocol];
|
||||
ret << " to ";
|
||||
ret << config_.client_name;
|
||||
}
|
||||
return ret;
|
||||
else
|
||||
ret << "Streaming terminated.";
|
||||
return ret.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,10 +41,13 @@ public:
|
||||
|
||||
void enable(bool on);
|
||||
void setSession(Session *se);
|
||||
void removeStreams(const std::string &ip);
|
||||
void removeStreams(const std::string &clientname);
|
||||
|
||||
bool busy() const;
|
||||
std::vector<std::string> listStreams() const;
|
||||
|
||||
protected:
|
||||
void addStream(const std::string &sender, int reply_to);
|
||||
void addStream(const std::string &sender, int reply_to, const std::string &clientname);
|
||||
void removeStream(const std::string &sender, int port);
|
||||
|
||||
private:
|
||||
|
||||
@@ -1105,7 +1105,6 @@ void UserInterface::RenderPreview()
|
||||
}
|
||||
|
||||
FrameGrabber *rec = Mixer::manager().session()->getFrameGrabber(video_recorder_);
|
||||
// FrameGrabber *str = Mixer::manager().session()->getFrameGrabber(video_streamer_);
|
||||
|
||||
// return from thread for folder openning
|
||||
if ( !recordFolderFileDialogs.empty() ) {
|
||||
@@ -1210,72 +1209,21 @@ void UserInterface::RenderPreview()
|
||||
Streaming::manager().enable(Settings::application.accept_connections);
|
||||
}
|
||||
ImGui::PopStyleColor(1);
|
||||
if (Settings::application.accept_connections)
|
||||
{
|
||||
static char dummy_str[512];
|
||||
sprintf(dummy_str, "%s", Connection::manager().info().name.c_str());
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
ImGui::InputText("Name", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
|
||||
|
||||
ImGui::Separator();
|
||||
std::vector<std::string> ls = Streaming::manager().listStreams();
|
||||
for (auto it = ls.begin(); it != ls.end(); it++)
|
||||
ImGui::Text("%s", (*it).c_str() );
|
||||
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
// if (ImGui::BeginMenu("Stream"))
|
||||
// {
|
||||
// // Stop recording menu if main recorder already exists
|
||||
// if (str) {
|
||||
// ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.05, 1.0, 0.05, 0.8f));
|
||||
// if ( ImGui::MenuItem( ICON_FA_SQUARE " Stop Streaming") ) {
|
||||
// str->stop();
|
||||
// video_streamer_ = 0;
|
||||
// }
|
||||
// ImGui::PopStyleColor(1);
|
||||
// if (video_streamer_ > 0) {
|
||||
// if (Settings::application.stream.profile == NetworkToolkit::TCP_JPEG || Settings::application.stream.profile == NetworkToolkit::TCP_H264) {
|
||||
// // Options menu
|
||||
// ImGui::Separator();
|
||||
// ImGui::MenuItem("Connection parameters", nullptr, false, false);
|
||||
// static char dummy_str[512];
|
||||
// sprintf(dummy_str, "%s", Settings::application.stream.ip.c_str());
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// ImGui::InputText("Host", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
|
||||
// sprintf(dummy_str, "%d", Settings::application.stream.port);
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// ImGui::InputText("Port", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
|
||||
// }
|
||||
|
||||
// }
|
||||
// }
|
||||
// // start recording
|
||||
// else {
|
||||
// // detecting the absence of video streamer but the variable is still not 0: fix this!
|
||||
// if (video_streamer_ > 0)
|
||||
// video_streamer_ = 0;
|
||||
// ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.05, 1.0, 0.05, 0.8f));
|
||||
// if ( ImGui::MenuItem( ICON_FA_PODCAST " Stream") ) {
|
||||
// FrameGrabber *fg = new VideoStreamer;
|
||||
// video_streamer_ = fg->id();
|
||||
// Mixer::manager().session()->addFrameGrabber(fg);
|
||||
// Streaming::manager().enable(true);
|
||||
// }
|
||||
// ImGui::PopStyleColor(1);
|
||||
// // select profile
|
||||
// ImGui::SetNextItemWidth(300);
|
||||
// ImGui::Combo("##StreamProfile", &Settings::application.stream.profile, NetworkToolkit::protocol_name, IM_ARRAYSIZE(NetworkToolkit::protocol_name) );
|
||||
|
||||
// if (Settings::application.stream.profile == NetworkToolkit::TCP_JPEG || Settings::application.stream.profile == NetworkToolkit::TCP_H264) {
|
||||
// // Options menu
|
||||
// ImGui::Separator();
|
||||
// ImGui::MenuItem("TCP Options", nullptr, false, false);
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// if (ImGui::BeginCombo("Host", Settings::application.stream.ip.c_str()))
|
||||
// {
|
||||
// static std::vector<std::string> ips = NetworkToolkit::host_ips();
|
||||
// for (int i=0; i < ips.size(); i++) {
|
||||
// if (ImGui::Selectable( ips[i].c_str() ))
|
||||
// Settings::application.stream.ip = ips[i];
|
||||
// }
|
||||
// ImGui::EndCombo();
|
||||
// }
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// ImGui::InputInt("Port", &Settings::application.stream.port, 100, 1000);
|
||||
// Settings::application.stream.port = CLAMP(Settings::application.stream.port, 1000, 9000);
|
||||
// }
|
||||
// }
|
||||
// ImGui::EndMenu();
|
||||
// }
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
@@ -1307,19 +1255,19 @@ void UserInterface::RenderPreview()
|
||||
ImGui::PopFont();
|
||||
}
|
||||
// streaming indicator overlay
|
||||
// if (str)
|
||||
// {
|
||||
// float r = ImGui::GetTextLineHeightWithSpacing();
|
||||
// ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + width - 2.f * r, draw_pos.y + r));
|
||||
// ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
|
||||
// if (str->busy())
|
||||
// ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.05, 1.0, 0.05, 0.8f));
|
||||
// else
|
||||
// ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.05, 1.0, 0.05, 0.2f));
|
||||
// ImGui::Text(ICON_FA_PODCAST);
|
||||
// ImGui::PopStyleColor(1);
|
||||
// ImGui::PopFont();
|
||||
// }
|
||||
if (Settings::application.accept_connections)
|
||||
{
|
||||
float r = ImGui::GetTextLineHeightWithSpacing();
|
||||
ImGui::SetCursorScreenPos(ImVec2(draw_pos.x + width - 2.f * r, draw_pos.y + r));
|
||||
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
|
||||
if ( Streaming::manager().busy())
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.05, 1.0, 0.05, 0.8f));
|
||||
else
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.05, 1.0, 0.05, 0.2f));
|
||||
ImGui::Text(ICON_FA_PODCAST);
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user