Managing client name and disconnection (e.g. end vimix)

This commit is contained in:
brunoherbelin
2020-10-25 18:56:56 +01:00
parent 8fa14bda1a
commit e60c7a4cad
8 changed files with 97 additions and 99 deletions

View File

@@ -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
}

View File

@@ -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 ?
}
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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:

View File

@@ -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();
}