@@ -388,6 +388,7 @@ async fn download_video(pool: SqlitePool) -> Result<(), Box<dyn std::error::Erro
388
388
389
389
let downloaded_video_frame_count: f64 = downloaded_video_cap. get ( CAP_PROP_FRAME_COUNT ) ?;
390
390
let frame_count_diff = ( downloaded_video_frame_count - 20.0 ) . abs ( ) ;
391
+ // ! This is flaky, can fail sometimes
391
392
assert ! ( frame_count_diff <= 3.0 ) ;
392
393
393
394
let mut downloaded_video_frame = Mat :: default ( ) ;
@@ -486,3 +487,119 @@ async fn home_feeds(pool: SqlitePool) -> Result<(), Box<dyn std::error::Error +
486
487
487
488
Ok ( ( ) )
488
489
}
490
+
491
+ #[ sqlx:: test( fixtures(
492
+ path = "../fixtures" ,
493
+ scripts( "users" , "cameras" , "camera_permissions" , "videos" )
494
+ ) ) ]
495
+ async fn multi_camera_record (
496
+ pool : SqlitePool ,
497
+ ) -> Result < ( ) , Box < dyn std:: error:: Error + Send + Sync > > {
498
+ let ( _p, _context, _addr_str, addr, video_temp_dir) = utils:: setup ( & pool) . await ?;
499
+
500
+ let video_list = Video :: list_for_camera ( & pool, 2 ) . await ?;
501
+ assert_eq ! ( video_list. len( ) , 1 ) ;
502
+
503
+ let video_path = video_temp_dir. path ( ) ;
504
+ let file_count = video_path. read_dir ( ) ?. count ( ) ;
505
+
506
+ let mut camera_1_ws_stream = utils:: setup_ws_with_port ( addr, 40000 ) . await ?;
507
+ let mut camera_2_ws_stream = utils:: setup_ws_with_port ( addr, 40001 ) . await ?;
508
+ camera_1_ws_stream
509
+ . send ( Message :: Text ( "camera" . to_string ( ) ) )
510
+ . await ?;
511
+ camera_2_ws_stream
512
+ . send ( Message :: Text ( "camera" . to_string ( ) ) )
513
+ . await ?;
514
+
515
+ let sent_frame_count = 20 ;
516
+
517
+ for _ in 0 ..sent_frame_count {
518
+ camera_1_ws_stream
519
+ . send ( Message :: Binary ( utils:: REAL_TEST_IMG_1 . into ( ) ) )
520
+ . await ?;
521
+
522
+ camera_2_ws_stream
523
+ . send ( Message :: Binary ( utils:: REAL_TEST_IMG_2 . into ( ) ) )
524
+ . await ?;
525
+
526
+ sleep ( Duration :: from_millis ( 80 ) ) . await ;
527
+ }
528
+
529
+ camera_1_ws_stream. close ( None ) . await ?;
530
+ camera_2_ws_stream. close ( None ) . await ?;
531
+ sleep ( Duration :: from_millis ( 80 ) ) . await ;
532
+
533
+ let camera_1_new_video_list = Video :: list_for_camera ( & pool, 1 ) . await ?;
534
+ let camera_2_new_video_list = Video :: list_for_camera ( & pool, 2 ) . await ?;
535
+ assert_eq ! ( camera_1_new_video_list. len( ) , 2 ) ;
536
+ assert_eq ! ( camera_2_new_video_list. len( ) , 2 ) ;
537
+
538
+ let new_file_count = video_path. read_dir ( ) ?. count ( ) ;
539
+ assert_eq ! ( new_file_count, file_count + 2 ) ;
540
+
541
+ let Some ( camera_1_newest_video) = camera_1_new_video_list. iter ( ) . max_by_key ( |v| v. video_id )
542
+ else {
543
+ return Err ( "No newest video found" . into ( ) ) ;
544
+ } ;
545
+ let Some ( camera_2_newest_video) = camera_2_new_video_list. iter ( ) . max_by_key ( |v| v. video_id )
546
+ else {
547
+ return Err ( "No newest video found" . into ( ) ) ;
548
+ } ;
549
+
550
+ let camera_1_created_video_path_str = camera_1_newest_video. file_path . clone ( ) ;
551
+ let camera_1_created_video_pathbuf = PathBuf :: from ( & camera_1_newest_video. file_path ) ;
552
+ let camera_2_created_video_path_str = camera_2_newest_video. file_path . clone ( ) ;
553
+ let camera_2_created_video_pathbuf = PathBuf :: from ( & camera_2_newest_video. file_path ) ;
554
+ assert ! ( camera_1_created_video_pathbuf. exists( ) ) ;
555
+ assert ! ( camera_2_created_video_pathbuf. exists( ) ) ;
556
+
557
+ let mut camera_1_created_video_cap =
558
+ VideoCapture :: from_file ( & camera_1_created_video_path_str, CAP_ANY ) ?;
559
+ if !camera_1_created_video_cap. is_opened ( ) ? {
560
+ return Err ( "Failed to open video file" . into ( ) ) ;
561
+ }
562
+ let mut camera_2_created_video_cap =
563
+ VideoCapture :: from_file ( & camera_2_created_video_path_str, CAP_ANY ) ?;
564
+ if !camera_2_created_video_cap. is_opened ( ) ? {
565
+ return Err ( "Failed to open video file" . into ( ) ) ;
566
+ }
567
+
568
+ let camera_1_created_video_frame_count: f64 =
569
+ camera_1_created_video_cap. get ( CAP_PROP_FRAME_COUNT ) ?;
570
+ let camera_1_frame_count_diff = ( camera_1_created_video_frame_count - 20.0 ) . abs ( ) ;
571
+ let camera_2_created_video_frame_count: f64 =
572
+ camera_2_created_video_cap. get ( CAP_PROP_FRAME_COUNT ) ?;
573
+ let camera_2_frame_count_diff = ( camera_2_created_video_frame_count - 20.0 ) . abs ( ) ;
574
+ // ! This is flaky, can fail sometimes
575
+ assert ! ( camera_1_frame_count_diff <= 3.0 ) ;
576
+ assert ! ( camera_2_frame_count_diff <= 3.0 ) ;
577
+
578
+ let mut camera_1_created_video_frame = Mat :: default ( ) ;
579
+ if !camera_1_created_video_cap. read ( & mut camera_1_created_video_frame) ? {
580
+ return Err ( "Failed to read frame" . into ( ) ) ;
581
+ }
582
+ let mut camera_2_created_video_frame = Mat :: default ( ) ;
583
+ if !camera_2_created_video_cap. read ( & mut camera_2_created_video_frame) ? {
584
+ return Err ( "Failed to read frame" . into ( ) ) ;
585
+ }
586
+
587
+ let camera_1_created_video_frame_data = camera_1_created_video_frame. data_bytes ( ) ?;
588
+ let camera_2_created_video_frame_data = camera_2_created_video_frame. data_bytes ( ) ?;
589
+
590
+ let camera_1_decoded_test_image = imdecode ( utils:: REAL_TEST_IMG_1 , IMREAD_COLOR ) ?;
591
+ let camera_1_decoded_test_image_data = camera_1_decoded_test_image. data_bytes ( ) ?;
592
+ let camera_2_decoded_test_image = imdecode ( utils:: REAL_TEST_IMG_2 , IMREAD_COLOR ) ?;
593
+ let camera_2_decoded_test_image_data = camera_2_decoded_test_image. data_bytes ( ) ?;
594
+
595
+ assert_eq ! (
596
+ camera_1_created_video_frame_data. len( ) ,
597
+ camera_1_decoded_test_image_data. len( )
598
+ ) ;
599
+ assert_eq ! (
600
+ camera_2_created_video_frame_data. len( ) ,
601
+ camera_2_decoded_test_image_data. len( )
602
+ ) ;
603
+
604
+ Ok ( ( ) )
605
+ }
0 commit comments