@@ -25,7 +25,7 @@ defmodule LiveExWebRTC.Publisher do
25
25
`{:live_ex_webrtc, :audio, ExRTP.Packet.t()}`. Packets for non-simulcast video tracks are always
26
26
sent with "h" identifier.
27
27
* `streams:info:#{publisher.id}"` - for receiving information about publisher tracks and their layers.
28
- The message is in form of: `{:live_ex_webrtc, :info, audio_track :: ExWebRTC.MediaStreamTrack.t(), video_track :: ExWebRTC.MediaStreamTrack.t()}`.
28
+ The message is in form of: `{:live_ex_webrtc, :info | :bye , audio_track :: ExWebRTC.MediaStreamTrack.t(), video_track :: ExWebRTC.MediaStreamTrack.t()}`.
29
29
* `publishers:#{publisher_id}` for sending keyframe request.
30
30
The message must be in form of `{:live_ex_webrtc, :keyframe_req, "l" | "m" | "h"}`
31
31
E.g.
@@ -139,6 +139,7 @@ defmodule LiveExWebRTC.Publisher do
139
139
140
140
defstruct id: nil ,
141
141
pc: nil ,
142
+ pc_mref: nil ,
142
143
streaming?: false ,
143
144
simulcast_supported?: nil ,
144
145
# record checkbox status
@@ -160,7 +161,8 @@ defmodule LiveExWebRTC.Publisher do
160
161
ice_port_range: nil ,
161
162
audio_codecs: nil ,
162
163
video_codecs: nil ,
163
- pc_genserver_opts: nil
164
+ pc_genserver_opts: nil ,
165
+ info_timer: nil
164
166
165
167
attr ( :socket , Phoenix.LiveView.Socket , required: true , doc: "Parent live view socket" )
166
168
@@ -507,7 +509,6 @@ defmodule LiveExWebRTC.Publisher do
507
509
socket =
508
510
receive do
509
511
{ ^ ref , % Publisher { id: ^ pub_id } = publisher } ->
510
- Process . send_after ( self ( ) , :streams_info , 1000 )
511
512
codecs = publisher . video_codecs || PeerConnection.Configuration . default_video_codecs ( )
512
513
publisher = % Publisher { publisher | simulcast_supported?: simulcast_supported? ( codecs ) }
513
514
assign ( socket , publisher: publisher )
@@ -522,7 +523,11 @@ defmodule LiveExWebRTC.Publisher do
522
523
end
523
524
524
525
@ impl true
525
- def handle_info ( { :live_ex_webrtc , :keyframe_req , layer } , socket ) do
526
+ def handle_info (
527
+ { :live_ex_webrtc , :keyframe_req , layer } ,
528
+ % { assigns: % { publisher: % { pc: pc } } } = socket
529
+ )
530
+ when pc != nil do
526
531
% { publisher: publisher } = socket . assigns
527
532
528
533
# Non-simulcast tracks are always sent with "h" identifier
@@ -535,9 +540,7 @@ defmodule LiveExWebRTC.Publisher do
535
540
layer
536
541
end
537
542
538
- if pc = publisher . pc do
539
- :ok = PeerConnection . send_pli ( pc , publisher . video_track . id , layer )
540
- end
543
+ :ok = PeerConnection . send_pli ( pc , publisher . video_track . id , layer )
541
544
542
545
{ :noreply , socket }
543
546
end
@@ -575,6 +578,10 @@ defmodule LiveExWebRTC.Publisher do
575
578
def handle_info ( { :ex_webrtc , _pid , { :connection_state_change , :connected } } , socket ) do
576
579
% { publisher: pub } = socket . assigns
577
580
581
+ info_timer = Process . send_after ( self ( ) , :streams_info , 1000 )
582
+ pub = % Publisher { pub | info_timer: info_timer }
583
+ socket = assign ( socket , :publisher , pub )
584
+
578
585
if pub . record? do
579
586
[
580
587
% { kind: :audio , receiver: % { track: audio_track } } ,
@@ -589,6 +596,11 @@ defmodule LiveExWebRTC.Publisher do
589
596
{ :noreply , socket }
590
597
end
591
598
599
+ @ impl true
600
+ def handle_info ( { :ex_webrtc , _pid , { :connection_state_change , :failed } } , socket ) do
601
+ { :noreply , bye ( socket ) }
602
+ end
603
+
592
604
@ impl true
593
605
def handle_info ( { :ex_webrtc , _ , _ } , socket ) do
594
606
{ :noreply , socket }
@@ -598,31 +610,33 @@ defmodule LiveExWebRTC.Publisher do
598
610
def handle_info ( :streams_info , socket ) do
599
611
% { publisher: publisher } = socket . assigns
600
612
601
- PubSub . broadcast (
602
- publisher . pubsub ,
603
- "streams:info:#{ publisher . id } " ,
604
- { :live_ex_webrtc , :info , publisher . audio_track , publisher . video_track }
605
- )
606
-
607
- Process . send_after ( self ( ) , :streams_info , 1_000 )
608
-
609
- { :noreply , socket }
613
+ if publisher . audio_track != nil or publisher . video_track != nil do
614
+ PubSub . broadcast (
615
+ publisher . pubsub ,
616
+ "streams:info:#{ publisher . id } " ,
617
+ { :live_ex_webrtc , :info , publisher . audio_track , publisher . video_track }
618
+ )
619
+
620
+ info_timer = Process . send_after ( self ( ) , :streams_info , 1_000 )
621
+ publisher = % Publisher { publisher | info_timer: info_timer }
622
+ socket = assign ( socket , :publisher , publisher )
623
+ { :noreply , socket }
624
+ else
625
+ { :noreply , socket }
626
+ end
610
627
end
611
628
629
+ @ impl true
612
630
def handle_info (
613
631
{ :DOWN , _ref , :process , pc , _reason } ,
614
- % { assigns: % { publisher: % { pc: pc } = pub } } = socket
632
+ % { assigns: % { publisher: % { pc: pc } } } = socket
615
633
) do
616
- if pub . record? do
617
- recorder_result =
618
- Recorder . end_tracks ( pub . recorder , [ pub . audio_track . id , pub . video_track . id ] )
619
-
620
- if pub . on_recording_finished , do: pub . on_recording_finished . ( pub . id , recorder_result )
621
- end
622
-
623
- if pub . on_disconnected , do: pub . on_disconnected . ( pub . id )
634
+ { :noreply , bye ( socket ) }
635
+ end
624
636
625
- { :noreply , assign ( socket , publisher: % Publisher { pub | streaming?: false } ) }
637
+ @ impl true
638
+ def handle_info ( _msg , socket ) do
639
+ { :noreply , socket }
626
640
end
627
641
628
642
@ impl true
@@ -647,27 +661,21 @@ defmodule LiveExWebRTC.Publisher do
647
661
648
662
@ impl true
649
663
def handle_event ( "stop-streaming" , _ , socket ) do
650
- { :noreply ,
651
- socket
652
- |> assign ( publisher: % Publisher { socket . assigns . publisher | streaming?: false } )
653
- |> push_event ( "stop-streaming" , % { } ) }
664
+ { :noreply , bye ( socket ) }
654
665
end
655
666
656
667
@ impl true
657
668
def handle_event ( "record-stream-change" , params , socket ) do
658
669
record? = params [ "value" ] == "on"
659
-
660
- { :noreply ,
661
- socket
662
- |> assign ( publisher: % Publisher { socket . assigns . publisher | record?: record? } ) }
670
+ { :noreply , assign ( socket , publisher: % Publisher { socket . assigns . publisher | record?: record? } ) }
663
671
end
664
672
665
673
@ impl true
666
674
def handle_event ( "offer" , unsigned_params , socket ) do
667
675
% { publisher: publisher } = socket . assigns
668
676
offer = SessionDescription . from_json ( unsigned_params )
669
677
{ :ok , pc } = spawn_peer_connection ( socket )
670
- Process . monitor ( pc )
678
+ pc_mref = Process . monitor ( pc )
671
679
672
680
:ok = PeerConnection . set_remote_description ( pc , offer )
673
681
@@ -687,6 +695,7 @@ defmodule LiveExWebRTC.Publisher do
687
695
new_publisher = % Publisher {
688
696
publisher
689
697
| pc: pc ,
698
+ pc_mref: pc_mref ,
690
699
audio_track: audio_track ,
691
700
video_track: video_track
692
701
}
@@ -731,6 +740,9 @@ defmodule LiveExWebRTC.Publisher do
731
740
end
732
741
end
733
742
743
+ @ impl true
744
+ def terminate ( _reason , socket ) , do: bye ( socket )
745
+
734
746
defp spawn_peer_connection ( socket ) do
735
747
% { publisher: publisher } = socket . assigns
736
748
@@ -770,4 +782,58 @@ defmodule LiveExWebRTC.Publisher do
770
782
false
771
783
end )
772
784
end
785
+
786
+ defp bye ( socket ) do
787
+ % { publisher: publisher } = socket . assigns
788
+
789
+ if publisher . audio_track != nil or publisher . video_track != nil do
790
+ PubSub . broadcast (
791
+ publisher . pubsub ,
792
+ "streams:info:#{ publisher . id } " ,
793
+ { :live_ex_webrtc , :bye , publisher . audio_track , publisher . video_track }
794
+ )
795
+ end
796
+
797
+ if publisher . info_timer != nil , do: Process . cancel_timer ( publisher . info_timer )
798
+
799
+ receive do
800
+ :streams_info -> :ok
801
+ after
802
+ 0 -> :ok
803
+ end
804
+
805
+ try do
806
+ Process . demonitor ( publisher . pc_mref )
807
+ PeerConnection . close ( publisher . pc )
808
+ catch
809
+ _ , _ -> :ok
810
+ end
811
+
812
+ if publisher . record? and publisher . audio_track != nil and publisher . video_track != nil do
813
+ recorder_result =
814
+ Recorder . end_tracks ( publisher . recorder , [
815
+ publisher . audio_track . id ,
816
+ publisher . video_track . id
817
+ ] )
818
+
819
+ if publisher . on_recording_finished ,
820
+ do: publisher . on_recording_finished . ( publisher . id , recorder_result )
821
+ end
822
+
823
+ if publisher . on_disconnected , do: publisher . on_disconnected . ( publisher . id )
824
+
825
+ publisher = % Publisher {
826
+ publisher
827
+ | info_timer: nil ,
828
+ audio_track: nil ,
829
+ video_track: nil ,
830
+ streaming?: false ,
831
+ pc: nil ,
832
+ pc_mref: nil
833
+ }
834
+
835
+ socket
836
+ |> assign ( :publisher , publisher )
837
+ |> push_event ( "stop-streaming" , % { } )
838
+ end
773
839
end
0 commit comments