Trigger ads in exact time, slate not even visible
This commit is contained in:
parent
455637af2a
commit
2b2fa32796
3 changed files with 214 additions and 14 deletions
150
Cargo.lock
generated
150
Cargo.lock
generated
|
@ -131,6 +131,45 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "3.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"clap_derive",
|
||||||
|
"clap_lex",
|
||||||
|
"indexmap",
|
||||||
|
"lazy_static",
|
||||||
|
"strsim",
|
||||||
|
"termcolor",
|
||||||
|
"textwrap",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "3.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669"
|
||||||
|
dependencies = [
|
||||||
|
"os_str_bytes",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color-name"
|
name = "color-name"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -254,6 +293,16 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
|
@ -500,6 +549,12 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -524,6 +579,17 @@ dependencies = [
|
||||||
"quick-error",
|
"quick-error",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.23.14"
|
version = "0.23.14"
|
||||||
|
@ -562,6 +628,16 @@ version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jpeg-decoder"
|
name = "jpeg-decoder"
|
||||||
version = "0.1.22"
|
version = "0.1.22"
|
||||||
|
@ -592,6 +668,12 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matches"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.1"
|
version = "2.4.1"
|
||||||
|
@ -732,12 +814,24 @@ dependencies = [
|
||||||
"paste",
|
"paste",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_str_bytes"
|
||||||
|
version = "6.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
|
checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -983,6 +1077,12 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3ff2f71c82567c565ba4b3009a9350a96a7269eaa4001ebedae926230bc2254"
|
checksum = "a3ff2f71c82567c565ba4b3009a9350a96a7269eaa4001ebedae926230bc2254"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.91"
|
version = "1.0.91"
|
||||||
|
@ -1016,6 +1116,12 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.30"
|
version = "1.0.30"
|
||||||
|
@ -1047,6 +1153,21 @@ dependencies = [
|
||||||
"weezl",
|
"weezl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.8"
|
version = "0.5.8"
|
||||||
|
@ -1072,12 +1193,39 @@ dependencies = [
|
||||||
"strength_reduce",
|
"strength_reduce",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"matches",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1094,6 +1242,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
name = "webvttconverter"
|
name = "webvttconverter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"eyre",
|
"eyre",
|
||||||
"glib",
|
"glib",
|
||||||
|
@ -1103,6 +1252,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -15,5 +15,7 @@ signal-hook = "0.3.13"
|
||||||
#axum = "0.4.5"
|
#axum = "0.4.5"
|
||||||
#tower = "0.4.12"
|
#tower = "0.4.12"
|
||||||
#tower-http = { version = "0.2.2", features = ["add-extension"] }
|
#tower-http = { version = "0.2.2", features = ["add-extension"] }
|
||||||
|
clap = { version = "3" , features = ["derive"] }
|
||||||
|
url = "2"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
pretty_env_logger = "0.4.0"
|
pretty_env_logger = "0.4.0"
|
||||||
|
|
76
src/main.rs
76
src/main.rs
|
@ -1,11 +1,13 @@
|
||||||
use glib::translate::ToGlibPtr;
|
use glib::translate::ToGlibPtr;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
use log::{debug, info};
|
use log::{debug, info, trace};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use clap::Parser;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
fn send_splice<C>(element: &gst::Element, gst_sit: C)
|
fn send_splice<C>(element: &gst::Element, gst_sit: C)
|
||||||
where
|
where
|
||||||
|
@ -49,6 +51,30 @@ impl EventId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[clap(author, version, about, long_about = None)]
|
||||||
|
struct Configuration {
|
||||||
|
/// HLS input source of the stream
|
||||||
|
#[clap(short='s', long)]
|
||||||
|
hls_source_url: String,
|
||||||
|
|
||||||
|
/// RTP destination for the stream
|
||||||
|
#[clap(short='d', long)]
|
||||||
|
rtp_destination_url: String,
|
||||||
|
|
||||||
|
/// Image of the frame used as reference to trigger the SCTE35 event
|
||||||
|
#[clap(short='i', long)]
|
||||||
|
slate_image_path: String,
|
||||||
|
|
||||||
|
/// The SCTE35 stream PID
|
||||||
|
#[clap(short='p', long, default_value="500")]
|
||||||
|
scte_pid: u32,
|
||||||
|
|
||||||
|
/// The duration of the SCTE35 Splice event in seconds
|
||||||
|
#[clap(short='d', long)]
|
||||||
|
scte_duration_secs: u64,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
pretty_env_logger::init_timed();
|
pretty_env_logger::init_timed();
|
||||||
gst::init()?;
|
gst::init()?;
|
||||||
|
@ -57,14 +83,15 @@ fn main() -> eyre::Result<()> {
|
||||||
gst_mpegts::gst_mpegts_initialize();
|
gst_mpegts::gst_mpegts_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ! filesink sync=true location=video.ts
|
let conf: Configuration = Configuration::parse();
|
||||||
|
|
||||||
let pipeline = gst::parse_launch(
|
let pipeline = gst::parse_launch(
|
||||||
r#"
|
r#"
|
||||||
|
|
||||||
urisourcebin uri=https://plutolive-msl.akamaized.net/hls/live/2008623/defy/master.m3u8 ! tsdemux name=demux ! queue ! h264parse ! tee name=v
|
urisourcebin name=source ! tsdemux name=demux ! queue ! h264parse ! tee name=v
|
||||||
|
|
||||||
v. ! queue ! mpegtsmux name=mux scte-35-pid=500 scte-35-null-interval=450000 ! rtpmp2tpay ! udpsink sync=true host=54.225.215.79 port=5000
|
v. ! queue ! mpegtsmux name=mux scte-35-null-interval=450000 ! rtpmp2tpay ! udpsink name=rtpsink sync=true
|
||||||
v. ! queue ! decodebin ! videoconvert ! imgcmp name=imgcmp location=/Users/rafaelcaricio/Downloads/defy-AD-SLATE-APRIL3022.jpeg ! autovideosink
|
v. ! queue ! decodebin ! videoconvert ! imgcmp name=imgcmp ! autovideosink
|
||||||
|
|
||||||
demux. ! queue ! aacparse ! mux.
|
demux. ! queue ! aacparse ! mux.
|
||||||
"#,
|
"#,
|
||||||
|
@ -74,6 +101,28 @@ fn main() -> eyre::Result<()> {
|
||||||
|
|
||||||
info!("Starting pipeline...");
|
info!("Starting pipeline...");
|
||||||
|
|
||||||
|
// Set the HLS source URL
|
||||||
|
let source = pipeline.by_name("source").unwrap();
|
||||||
|
source.set_property("uri", conf.hls_source_url);
|
||||||
|
|
||||||
|
// Set SCTE35 stream PID
|
||||||
|
let mux = pipeline.by_name("mux").unwrap();
|
||||||
|
mux.set_property("scte-35-pid", conf.scte_pid);
|
||||||
|
|
||||||
|
// Set the frame we are searching for
|
||||||
|
let imgcmp = pipeline.by_name("imgcmp").unwrap();
|
||||||
|
imgcmp.set_property("location", conf.slate_image_path);
|
||||||
|
|
||||||
|
// Set the RTP destination
|
||||||
|
let rtp_url = Url::parse(&conf.rtp_destination_url).expect("Valid URL in format rtp://<host>:<port>");
|
||||||
|
let rtp_sink = pipeline.by_name("rtpsink").unwrap();
|
||||||
|
rtp_sink.set_properties(&[
|
||||||
|
("host", &rtp_url.host_str().unwrap().to_string()),
|
||||||
|
("port", &(rtp_url.port().unwrap() as i32)),
|
||||||
|
// In order to make sure the slate image is not event visible, we delay 1 second
|
||||||
|
("ts-offset", &(gst::ClockTime::from_seconds(1).nseconds() as i64)),
|
||||||
|
]);
|
||||||
|
|
||||||
let context = glib::MainContext::default();
|
let context = glib::MainContext::default();
|
||||||
let main_loop = glib::MainLoop::new(Some(&context), false);
|
let main_loop = glib::MainLoop::new(Some(&context), false);
|
||||||
|
|
||||||
|
@ -83,10 +132,12 @@ fn main() -> eyre::Result<()> {
|
||||||
bus.add_watch({
|
bus.add_watch({
|
||||||
let event_counter = EventId::default();
|
let event_counter = EventId::default();
|
||||||
let ad_running = Arc::new(AtomicBool::new(false));
|
let ad_running = Arc::new(AtomicBool::new(false));
|
||||||
|
let ad_duration = Duration::from_secs(conf.scte_duration_secs);
|
||||||
|
|
||||||
let main_loop = main_loop.clone();
|
let main_loop = main_loop.clone();
|
||||||
let pipeline_weak = pipeline.downgrade();
|
let pipeline_weak = pipeline.downgrade();
|
||||||
let imgcmp_weak = pipeline.by_name("imgcmp").unwrap().downgrade();
|
let imgcmp_weak = imgcmp.downgrade();
|
||||||
let muxer_weak = pipeline.by_name("mux").unwrap().downgrade();
|
let muxer_weak = mux.downgrade();
|
||||||
move |_, msg| {
|
move |_, msg| {
|
||||||
use gst::MessageView;
|
use gst::MessageView;
|
||||||
|
|
||||||
|
@ -121,7 +172,7 @@ fn main() -> eyre::Result<()> {
|
||||||
imgcmp_weak.upgrade(),
|
imgcmp_weak.upgrade(),
|
||||||
muxer_weak.upgrade(),
|
muxer_weak.upgrade(),
|
||||||
) {
|
) {
|
||||||
info!("Element Message: {:?}", elem_msg);
|
trace!("Element Message: {:?}", elem_msg);
|
||||||
if elem_msg.src().map(|e| e == imgcmp).unwrap_or(false)
|
if elem_msg.src().map(|e| e == imgcmp).unwrap_or(false)
|
||||||
&& elem_msg.message().has_name("image-detected")
|
&& elem_msg.message().has_name("image-detected")
|
||||||
&& !ad_running.load(Ordering::Relaxed)
|
&& !ad_running.load(Ordering::Relaxed)
|
||||||
|
@ -130,24 +181,21 @@ fn main() -> eyre::Result<()> {
|
||||||
// is, so we use the pipeline running time to base our timing calculations
|
// is, so we use the pipeline running time to base our timing calculations
|
||||||
let now = pipeline.current_running_time().unwrap();
|
let now = pipeline.current_running_time().unwrap();
|
||||||
|
|
||||||
// How much ahead should the ad be inserted, we say 0 seconds in the future (immediate)
|
|
||||||
let ahead = gst::ClockTime::from_seconds(0);
|
|
||||||
|
|
||||||
// Trigger the Splice Out event in the SCTE-35 stream
|
// Trigger the Splice Out event in the SCTE-35 stream
|
||||||
send_splice_out(&muxer, event_counter.next(), now + ahead);
|
send_splice_out(&muxer, event_counter.next(), now);
|
||||||
ad_running.store(true, Ordering::Relaxed);
|
ad_running.store(true, Ordering::Relaxed);
|
||||||
info!("Ad started..");
|
info!("Ad started..");
|
||||||
|
|
||||||
// Now we add a timed call for the duration of the ad from now to indicate via
|
// Now we add a timed call for the duration of the ad from now to indicate via
|
||||||
// splice in that the stream can go back to normal programming.
|
// splice in that the stream can go back to normal programming.
|
||||||
glib::timeout_add(Duration::from_secs(30), {
|
glib::timeout_add(ad_duration, {
|
||||||
let muxer_weak = muxer.downgrade();
|
let muxer_weak = muxer.downgrade();
|
||||||
let event_counter = event_counter.clone();
|
let event_counter = event_counter.clone();
|
||||||
let ad_running = Arc::clone(&ad_running);
|
let ad_running = Arc::clone(&ad_running);
|
||||||
move || {
|
move || {
|
||||||
if let Some(muxer) = muxer_weak.upgrade() {
|
if let Some(muxer) = muxer_weak.upgrade() {
|
||||||
let now = muxer.current_running_time().unwrap();
|
let now = muxer.current_running_time().unwrap();
|
||||||
send_splice_in(&muxer, event_counter.next(), now + ahead);
|
send_splice_in(&muxer, event_counter.next(), now);
|
||||||
ad_running.store(false, Ordering::Relaxed);
|
ad_running.store(false, Ordering::Relaxed);
|
||||||
info!("Ad ended!")
|
info!("Ad ended!")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue