зеркало из https://github.com/microsoft/auteur.git
Initial code
This commit is contained in:
Родитель
98d588b04f
Коммит
c293cf59a5
|
@ -348,3 +348,5 @@ MigrationBackup/
|
|||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
/target
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,5 @@
|
|||
[workspace]
|
||||
|
||||
members = [
|
||||
"server",
|
||||
]
|
34
LICENSE
34
LICENSE
|
@ -1,21 +1,21 @@
|
|||
MIT License
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Project
|
||||
# RTMP switcher
|
||||
|
||||
> This repo has been populated by an initial template to help get you started. Please
|
||||
> make sure to update the content to build a great experience for community-building.
|
||||
|
@ -31,3 +31,7 @@ trademarks or logos is subject to and must follow
|
|||
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
|
||||
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
||||
Any use of third-party trademarks or logos are subject to those third-party's policies.
|
||||
|
||||
## License
|
||||
|
||||
All code in this repository is licensed under the [MIT license](LICENSE).
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
[package]
|
||||
name = "rtmp-switcher"
|
||||
version = "0.1.0"
|
||||
authors = ["Mathieu Duponchelle <mathieu@centricular.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
gst = { version = "0.16", package = "gstreamer" }
|
||||
gst-base = { version = "0.16", package = "gstreamer-base" }
|
||||
gst-app = { version = "0.16", package = "gstreamer-app" }
|
||||
glib = "0.10"
|
||||
futures = "0.3"
|
||||
actix = "0.10"
|
||||
actix-rt = "1"
|
||||
actix-web = { version = "3", features = ["openssl"] }
|
||||
actix-web-actors = "3"
|
||||
actix-service = "1"
|
||||
actix-files = "0.4"
|
||||
actix-cors = "0.5"
|
||||
openssl = "0.10"
|
||||
log = "0.4"
|
||||
env_logger = "0.8"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
structopt = "0.3"
|
||||
uuid = { version = "0.8", features = ["v4"] }
|
||||
chrono = "0.4"
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2021 Mathieu Duponchelle <mathieu@centricular.com>
|
||||
//
|
||||
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
|
||||
|
||||
use structopt::StructOpt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, StructOpt)]
|
||||
#[structopt(
|
||||
name = "rtmp-switcher",
|
||||
about = "Manages RTMP channels through a REST API"
|
||||
)]
|
||||
pub struct Config {
|
||||
/// Port to use.
|
||||
#[structopt(short, long, default_value = "8080")]
|
||||
pub port: u16,
|
||||
/// Use TLS.
|
||||
#[structopt(short = "t", long, requires("certificate-file"), requires("key-file"))]
|
||||
pub use_tls: bool,
|
||||
/// Certificate public key file.
|
||||
#[structopt(short = "c", long)]
|
||||
pub certificate_file: Option<PathBuf>,
|
||||
/// Certificate private key file.
|
||||
#[structopt(short = "k", long)]
|
||||
pub key_file: Option<PathBuf>,
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (C) 2021 Mathieu Duponchelle <mathieu@centricular.com>
|
||||
//
|
||||
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
|
||||
|
||||
mod config;
|
||||
mod server;
|
||||
|
||||
use anyhow::Error;
|
||||
use structopt::StructOpt;
|
||||
|
||||
use config::Config;
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
let cfg = Config::from_args();
|
||||
|
||||
gst::init()?;
|
||||
|
||||
let env = env_logger::Env::new()
|
||||
.filter_or("RTMP_SWITCHER_LOG", "warn")
|
||||
.write_style("RTMP_SWITCHER_LOG_STYLE");
|
||||
env_logger::init_from_env(env);
|
||||
|
||||
let mut system = actix_rt::System::new("WebRTC Audio Server");
|
||||
system.block_on(server::run(cfg))?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (C) 2021 Mathieu Duponchelle <mathieu@centricular.com>
|
||||
//
|
||||
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};
|
||||
use actix_web_actors::ws;
|
||||
|
||||
use log::error;
|
||||
|
||||
/// Create Subscriber/Publisher WebSocket actors.
|
||||
async fn ws(
|
||||
cfg: web::Data<Config>,
|
||||
path: web::Path<String>,
|
||||
req: HttpRequest,
|
||||
stream: web::Payload,
|
||||
) -> Result<HttpResponse, actix_web::Error> {
|
||||
match path.as_str() {
|
||||
"control" => {
|
||||
/*
|
||||
let publisher = Publisher::new(
|
||||
cfg.into_inner(),
|
||||
rooms.as_ref().clone(),
|
||||
&req.connection_info(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
error!("Failed to create publisher: {}", err);
|
||||
HttpResponse::InternalServerError()
|
||||
})?;
|
||||
|
||||
ws::start(publisher, &req, stream)
|
||||
*/
|
||||
Ok(HttpResponse::NotFound().finish())
|
||||
}
|
||||
_ => Ok(HttpResponse::NotFound().finish()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Start the server based on the passed `Config`.
|
||||
pub async fn run(cfg: Config) -> Result<(), anyhow::Error> {
|
||||
let cfg = web::Data::new(cfg);
|
||||
let cfg_clone = cfg.clone();
|
||||
|
||||
let server = HttpServer::new(move || {
|
||||
let cors = actix_cors::Cors::default().allow_any_origin().max_age(3600);
|
||||
|
||||
App::new()
|
||||
.wrap(actix_web::middleware::Logger::default())
|
||||
.wrap(cors)
|
||||
.app_data(cfg_clone.clone())
|
||||
.route("/ws/{mode:(control)}", web::get().to(ws))
|
||||
});
|
||||
|
||||
let server = if cfg.use_tls {
|
||||
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
||||
|
||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
|
||||
builder.set_private_key_file(
|
||||
cfg.key_file.as_ref().expect("No key file given"),
|
||||
SslFiletype::PEM,
|
||||
)?;
|
||||
builder.set_certificate_chain_file(
|
||||
cfg.certificate_file
|
||||
.as_ref()
|
||||
.expect("No certificate file given"),
|
||||
)?;
|
||||
|
||||
server.bind_openssl(format!("0.0.0.0:{}", cfg.port), builder)?
|
||||
} else {
|
||||
server.bind(format!("0.0.0.0:{}", cfg.port))?
|
||||
};
|
||||
|
||||
server.run().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
Загрузка…
Ссылка в новой задаче