support live streaming

This commit is contained in:
jazzfool 2020-10-10 13:05:34 +11:00
parent 09286fbb0f
commit 1cafb91105
2 changed files with 20 additions and 9 deletions

View file

@ -36,6 +36,7 @@ impl Application for App {
.unwrap(), .unwrap(),
) )
.unwrap(), .unwrap(),
false,
) )
.unwrap(), .unwrap(),
pause_btn: Default::default(), pause_btn: Default::default(),
@ -53,7 +54,9 @@ impl Application for App {
Message::TogglePause => { Message::TogglePause => {
self.video.set_paused(!self.video.paused()); self.video.set_paused(!self.video.paused());
} }
Message::VideoPlayerMessage(msg) => self.video.update(msg), Message::VideoPlayerMessage(msg) => {
self.video.update(msg);
}
} }
Command::none() Command::none()

View file

@ -95,7 +95,11 @@ impl Drop for VideoPlayer {
impl VideoPlayer { impl VideoPlayer {
/// Create a new video player from a given video which loads from `uri`. /// Create a new video player from a given video which loads from `uri`.
pub fn new(uri: &url::Url) -> Result<Self, Error> { ///
/// If `live` is set then no duration is queried (as this will result in an error and is non-sensical for live streams).
/// Set `live` if the streaming source is indefinite (e.g. a live stream).
/// Note that this will cause the duration to be zero.
pub fn new(uri: &url::Url, live: bool) -> Result<Self, Error> {
gst::init()?; gst::init()?;
let source = gst::parse_launch(&format!("playbin uri=\"{}\" video-sink=\"videoconvert ! videoscale ! appsink name=app_sink caps=video/x-raw,format=BGRA,pixel-aspect-ratio=1/1\"", uri.as_str()))?; let source = gst::parse_launch(&format!("playbin uri=\"{}\" video-sink=\"videoconvert ! videoscale ! appsink name=app_sink caps=video/x-raw,format=BGRA,pixel-aspect-ratio=1/1\"", uri.as_str()))?;
@ -179,13 +183,17 @@ impl VideoPlayer {
.map_err(|_| Error::Caps)? .map_err(|_| Error::Caps)?
.ok_or(Error::Caps)?; .ok_or(Error::Caps)?;
let duration = std::time::Duration::from_nanos( let duration = if !live {
source std::time::Duration::from_nanos(
.query_duration::<gst::ClockTime>() source
.ok_or(Error::Duration)? .query_duration::<gst::ClockTime>()
.nanoseconds() .ok_or(Error::Duration)?
.ok_or(Error::Duration)?, .nanoseconds()
); .ok_or(Error::Duration)?,
)
} else {
std::time::Duration::from_secs(0)
};
Ok(VideoPlayer { Ok(VideoPlayer {
bus: source.get_bus().unwrap(), bus: source.get_bus().unwrap(),