fcast_protocol/
lib.rs

1//! # FCast Protocol
2//!
3//! Implementation of the data models documented [here](https://gitlab.futo.org/videostreaming/fcast/-/wikis/Protocol-version-3).
4
5use serde::{Deserialize, Serialize};
6
7pub mod v2;
8pub mod v3;
9
10#[derive(Debug, thiserror::Error)]
11pub enum TryFromByteError {
12    #[error("Unknown opcode: {0}")]
13    UnknownOpcode(u8),
14}
15
16#[derive(Debug, PartialEq, Copy, Clone)]
17pub enum Opcode {
18    /// Not used
19    None = 0,
20    /// Sender message to play media content, body is [`v3::PlayMessage`]
21    Play = 1,
22    /// Sender message to pause media content, no body
23    Pause = 2,
24    /// Sender message to resume media content, no body
25    Resume = 3,
26    /// Sender message to stop media content, no body
27    Stop = 4,
28    /// Sender message to seek, body is [`SeekMessage`]
29    Seek = 5,
30    /// Receiver message to notify an updated playback state, body is [`v3::PlaybackUpdateMessage`]
31    PlaybackUpdate = 6,
32    /// Receiver message to notify when the volume has changed, body is [`VolumeUpdateMessage`]
33    VolumeUpdate = 7,
34    /// Sender message to change volume, body is [`SetVolumeMessage`]
35    SetVolume = 8,
36    /// Server message to notify the sender a playback error happened, body is [`PlaybackErrorMessage`]
37    PlaybackError = 9,
38    /// Sender message to change playback speed, body is [`SetSpeedMessage`]
39    SetSpeed = 10,
40    /// Message to notify the other of the current version, body is [`VersionMessage`]
41    Version = 11,
42    /// Message to get the other party to pong, no body
43    Ping = 12,
44    /// Message to respond to a ping from the other party, no body
45    Pong = 13,
46    /// Message to notify the other party of device information and state, body is InitialSenderMessage if receiver or
47    /// [`v3::InitialReceiverMessage`] if sender
48    Initial = 14,
49    /// Receiver message to notify all senders when any device has sent a [`v3::PlayMessage`], body is [`v3::PlayUpdateMessage`]
50    PlayUpdate = 15,
51    /// Sender message to set the item index in a playlist to play content from, body is [`v3::SetPlaylistItemMessage`]
52    SetPlaylistItem = 16,
53    /// Sender message to subscribe to a receiver event, body is [`v3::SubscribeEventMessage`]
54    SubscribeEvent = 17,
55    /// Sender message to unsubscribe to a receiver event, body is [`v3::UnsubscribeEventMessage`]
56    UnsubscribeEvent = 18,
57    /// Receiver message to notify when a sender subscribed event has occurred, body is [`v3::EventMessage`]
58    Event = 19,
59}
60
61impl TryFrom<u8> for Opcode {
62    type Error = TryFromByteError;
63
64    fn try_from(value: u8) -> Result<Self, Self::Error> {
65        Ok(match value {
66            0 => Opcode::None,
67            1 => Opcode::Play,
68            2 => Opcode::Pause,
69            3 => Opcode::Resume,
70            4 => Opcode::Stop,
71            5 => Opcode::Seek,
72            6 => Opcode::PlaybackUpdate,
73            7 => Opcode::VolumeUpdate,
74            8 => Opcode::SetVolume,
75            9 => Opcode::PlaybackError,
76            10 => Opcode::SetSpeed,
77            11 => Opcode::Version,
78            12 => Opcode::Ping,
79            13 => Opcode::Pong,
80            14 => Opcode::Initial,
81            15 => Opcode::PlayUpdate,
82            16 => Opcode::SetPlaylistItem,
83            17 => Opcode::SubscribeEvent,
84            18 => Opcode::UnsubscribeEvent,
85            19 => Opcode::Event,
86            _ => return Err(TryFromByteError::UnknownOpcode(value)),
87        })
88    }
89}
90
91#[allow(dead_code)]
92#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
93pub struct PlaybackErrorMessage {
94    pub message: String,
95}
96
97#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
98pub struct VersionMessage {
99    pub version: u64,
100}
101
102#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
103pub struct SetSpeedMessage {
104    pub speed: f64,
105}
106
107#[allow(dead_code)]
108#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
109pub struct VolumeUpdateMessage {
110    #[serde(rename = "generationTime")]
111    pub generation_time: u64,
112    pub volume: f64, //(0-1)
113}
114
115#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
116pub struct SetVolumeMessage {
117    pub volume: f64,
118}
119
120#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
121pub struct SeekMessage {
122    pub time: f64,
123}