1- use anyhow:: Result ;
1+ use anyhow:: { Result , anyhow } ;
22use ffmpeg_next:: { codec, filter, format, frame, media} ;
33use webrtc:: rtp:: codecs:: h264:: H264Packet ;
44use webrtc:: rtp:: packetizer:: Depacketizer ;
@@ -11,6 +11,7 @@ use std::io::Write;
1111use std:: mem:: zeroed;
1212use std:: ffi:: CStr ;
1313use std:: fs:: File ;
14+ use bytes:: Bytes ;
1415use std:: sync:: Arc ;
1516use std:: collections:: HashMap ;
1617use tokio:: sync:: { Mutex , Notify } ;
@@ -151,53 +152,11 @@ async fn create_peer_connection() -> Result<RTCPeerConnection, webrtc::Error> {
151152 api. new_peer_connection ( config) . await
152153}
153154
154- #[ tokio:: main]
155- async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
156- // XCloud part
157- let mut window = unsafe { zeroed ( ) } ;
158- let mut renderer = unsafe { zeroed ( ) } ;
159- let mut texture = unsafe { zeroed ( ) } ;
160-
161- unsafe {
162- if SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) == false {
163- println ! ( "SDL_Init Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
164- return Err ( "SDL Init failed" . into ( ) ) ;
165- }
166-
167- // Create a window
168- window = SDL_CreateWindow (
169- c"SDL3 Video Playback" . as_ptr ( ) ,
170- 1920 ,
171- 1080 ,
172- SDL_WindowFlags :: default ( )
173- ) ;
174-
175- if window. is_null ( ) {
176- println ! ( "SDL_CreateWindow Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
177- SDL_Quit ( ) ;
178- return Err ( "SDL_CreateWindow Error" . into ( ) ) ;
179- }
180-
181- renderer = SDL_CreateRenderer ( window, ptr:: null ( ) ) ;
182-
183- if renderer. is_null ( ) {
184- println ! ( "SDL_CreateRenderer Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
185- SDL_Quit ( ) ;
186- return Err ( "SDL_CreateRenderer Error" . into ( ) ) ;
187- }
188-
189- texture = SDL_CreateTexture ( renderer, SDL_PIXELFORMAT_IYUV , SDL_TEXTUREACCESS_STREAMING , 1920 , 1080 ) ;
190- if texture. is_null ( ) {
191- println ! ( "SDL_CreateTexture Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
192- SDL_Quit ( ) ;
193- return Err ( "SDL_CreateTexture Error" . into ( ) ) ;
194- }
195- }
196-
197-
198- let ts = authenticate ( TOKENS_FILEPATH ) . await ?;
155+ async fn start_remote_connection ( audio_tx : tokio:: sync:: mpsc:: Sender < Bytes > , video_tx : tokio:: sync:: mpsc:: Sender < Bytes > ) -> Result < ( ) > {
156+ let ts = authenticate ( TOKENS_FILEPATH )
157+ . await
158+ . map_err ( |e|anyhow ! ( "Authentication failed" ) ) ?;
199159
200- /*
201160 let xcloud = GamestreamingClient :: new (
202161 Platform :: Home ,
203162 & ts. gssv_token . token ,
@@ -211,11 +170,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
211170 xcloud. start_stream_xhome ( & c. server_id ) . await ?
212171 } ,
213172 Err ( err) => {
214- return Err("No consoles received from API".into( ));
173+ return Err ( anyhow ! ( "No consoles received from API" ) ) ;
215174 }
216175 } ;
217- */
218176
177+
178+ /*
219179 let xcloud = GamestreamingClient::new(
220180 Platform::Cloud,
221181 &ts.gssv_token.token,
@@ -234,6 +194,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
234194 return Err("No titles received from API".into());
235195 }
236196 };
197+ */
237198
238199 // WebRTC part
239200
@@ -389,9 +350,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
389350 ));
390351 */
391352
392- let ( mut video_tx, mut video_rx) = tokio:: sync:: mpsc:: channel ( 10 ) ;
393- let ( mut audio_tx, mut audio_rx) = tokio:: sync:: mpsc:: channel ( 10 ) ;
394-
395353 let notify_tx = Arc :: new ( Notify :: new ( ) ) ;
396354 let notify_rx = notify_tx. clone ( ) ;
397355
@@ -466,7 +424,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
466424 }
467425 None => {
468426 peer_connection. close ( ) . await ?;
469- return Err ( "Failed to get successful SDP answer" . into ( ) ) ;
427+ return Err ( anyhow ! ( "Failed to get successful SDP answer" ) ) ;
470428 }
471429 }
472430
@@ -489,6 +447,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
489447 let ice_response = xcloud. exchange_ice ( & session, candidates_ready) . await ?;
490448 println ! ( "ICE Response {:?}" , ice_response) ;
491449
450+ if ice_response. exchange_response . is_empty ( ) {
451+ return Err ( anyhow ! ( "No candidates in ICE response" ) ) ;
452+ }
453+
492454 println ! ( "Adding remote ICE candidates" ) ;
493455 for candidate in ice_response. exchange_response {
494456 println ! ( "Adding remote ICE candidate={:?}" , candidate) ;
@@ -505,6 +467,61 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
505467 peer_connection. add_ice_candidate ( c) . await ?;
506468 }
507469
470+ Ok ( ( ) )
471+ }
472+
473+ #[ tokio:: main]
474+ async fn main ( ) -> Result < ( ) > {
475+ // XCloud part
476+ let mut window = unsafe { zeroed ( ) } ;
477+ let mut renderer = unsafe { zeroed ( ) } ;
478+ let mut texture = unsafe { zeroed ( ) } ;
479+
480+ unsafe {
481+ if SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) == false {
482+ println ! ( "SDL_Init Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
483+ return Err ( anyhow ! ( "SDL Init failed" ) ) ;
484+ }
485+
486+ // Create a window
487+ window = SDL_CreateWindow (
488+ c"SDL3 Video Playback" . as_ptr ( ) ,
489+ 1920 ,
490+ 1080 ,
491+ SDL_WindowFlags :: default ( )
492+ ) ;
493+
494+ if window. is_null ( ) {
495+ println ! ( "SDL_CreateWindow Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
496+ SDL_Quit ( ) ;
497+ return Err ( anyhow ! ( "SDL_CreateWindow Error" ) ) ;
498+ }
499+
500+ renderer = SDL_CreateRenderer ( window, ptr:: null ( ) ) ;
501+
502+ if renderer. is_null ( ) {
503+ println ! ( "SDL_CreateRenderer Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
504+ SDL_Quit ( ) ;
505+ return Err ( anyhow ! ( "SDL_CreateRenderer Error" ) ) ;
506+ }
507+
508+ texture = SDL_CreateTexture ( renderer, SDL_PIXELFORMAT_IYUV , SDL_TEXTUREACCESS_STREAMING , 1920 , 1080 ) ;
509+ if texture. is_null ( ) {
510+ println ! ( "SDL_CreateTexture Error: {:?}" , CStr :: from_ptr( SDL_GetError ( ) ) ) ;
511+ SDL_Quit ( ) ;
512+ return Err ( anyhow ! ( "SDL_CreateTexture Error" ) ) ;
513+ }
514+ }
515+
516+ let ( mut video_tx, mut video_rx) = tokio:: sync:: mpsc:: channel ( 10 ) ;
517+ let ( mut audio_tx, mut audio_rx) = tokio:: sync:: mpsc:: channel ( 10 ) ;
518+
519+ println ! ( "Spawning remote connection..." ) ;
520+ let handle = tokio:: spawn ( start_remote_connection ( audio_tx, video_tx) ) ;
521+
522+
523+ // Create a channel to signal the main loop to exit
524+ let ( exit_tx, mut exit_rx) = tokio:: sync:: mpsc:: channel :: < ( ) > ( 1 ) ;
508525 println ! ( "Press ctrl-c to stop" ) ;
509526
510527 ffmpeg_next:: init ( ) ?;
@@ -516,9 +533,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
516533 . unwrap ( ) ;
517534
518535 unsafe {
519- // Create a channel to signal the main loop to exit
520- let ( exit_tx, mut exit_rx) = tokio:: sync:: mpsc:: channel :: < ( ) > ( 1 ) ;
521-
522536 // Clear the screen
523537 SDL_SetRenderDrawColor ( renderer, 0 , 0 , 0 , 255 ) ;
524538 SDL_RenderClear ( renderer) ;
@@ -535,7 +549,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
535549 let _ = exit_tx. send ( ( ) ) . await ;
536550 } ,
537551 _ => {
538- println ! ( "Unhandled evt: {:?}" , evt. r#type) ;
552+ // println!("Unhandled evt: {:?}", evt.r#type);
539553 }
540554 }
541555
@@ -581,11 +595,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
581595 }
582596 }
583597
584- /*
585598 SDL_DestroyRenderer ( renderer) ;
586599 SDL_DestroyWindow ( window) ;
587600 SDL_Quit ( ) ;
588- */
589601 }
590602
591603 Ok ( ( ) )
0 commit comments