桌面推流ok
This commit is contained in:
parent
b5df0c6374
commit
ff8769f4ac
|
|
@ -50,5 +50,7 @@ dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
|
|
||||||
implementation project(':zlm')
|
implementation project(':zlm')
|
||||||
|
implementation 'com.guolindev.permissionx:permissionx:1.7.1'
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,19 @@
|
||||||
package com.zlmediakit.webrtc
|
package com.zlmediakit.webrtc
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.permissionx.guolindev.PermissionX
|
||||||
|
import com.permissionx.guolindev.callback.RequestCallback
|
||||||
import com.zlm.rtc.ZLMRTCPusher
|
import com.zlm.rtc.ZLMRTCPusher
|
||||||
|
import com.zlm.rtc.push.PushMode
|
||||||
import com.zlm.rtc.push.ZLMRTCPusherImpl
|
import com.zlm.rtc.push.ZLMRTCPusherImpl
|
||||||
|
import kotlinx.android.synthetic.main.activity_player.surface_view_renderer
|
||||||
import kotlinx.android.synthetic.main.activity_player.tv_app
|
import kotlinx.android.synthetic.main.activity_player.tv_app
|
||||||
import kotlinx.android.synthetic.main.activity_player.tv_stream_id
|
import kotlinx.android.synthetic.main.activity_player.tv_stream_id
|
||||||
|
|
||||||
|
|
@ -16,23 +25,50 @@ class PusherDemoActivity: AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
}
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setContentView(R.layout.activity_pusher)
|
setContentView(R.layout.activity_pusher)
|
||||||
|
|
||||||
|
pusher.bind(surface_view_renderer, true)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onPushCamera(view: View) {
|
fun onPushCamera(view: View) {
|
||||||
|
PermissionX.init(this)
|
||||||
|
.permissions(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
|
||||||
|
.request { allGranted, grantedList, deniedList ->
|
||||||
|
if (allGranted) {
|
||||||
pusher.push(tv_app.text.toString(), tv_stream_id.text.toString())
|
pusher.push(tv_app.text.toString(), tv_stream_id.text.toString())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onPushScreen(view: View) {
|
||||||
|
PermissionX.init(this)
|
||||||
|
.permissions(Manifest.permission.RECORD_AUDIO)
|
||||||
|
.request { allGranted, grantedList, deniedList ->
|
||||||
|
if (allGranted) {
|
||||||
|
pusher.push(
|
||||||
|
tv_app.text.toString(),
|
||||||
|
tv_stream_id.text.toString(),
|
||||||
|
PushMode.SCREEN
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onPushFile(view: View) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
pusher.stop()
|
pusher.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<org.webrtc.SurfaceViewRenderer
|
<org.webrtc.SurfaceViewRenderer
|
||||||
android:id="@+id/surface_view_renderer"
|
android:id="@+id/surface_view_renderer"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="240dp" />
|
android:layout_height="240dp" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
v=0
|
||||||
|
o=- 6282534540641525368 2 IN IP4 127.0.0.1
|
||||||
|
s=-
|
||||||
|
t=0 0
|
||||||
|
a=group:BUNDLE 0 1 2
|
||||||
|
a=extmap-allow-mixed
|
||||||
|
a=msid-semantic: WMS
|
||||||
|
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:H2Ms
|
||||||
|
a=ice-pwd:14ODtTVh5+lT7W0+g9EAlE4j
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 47:81:90:07:43:95:D7:F2:DA:60:DA:79:E5:88:26:65:29:4A:26:28:7A:B7:AB:D3:DB:CE:C9:09:39:EB:31:91
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:0
|
||||||
|
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=sendrecv
|
||||||
|
a=msid:- ef1bcbd2-7e69-40d3-9532-0f4a698022a7
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtpmap:111 opus/48000/2
|
||||||
|
a=rtcp-fb:111 transport-cc
|
||||||
|
a=fmtp:111 minptime=10;useinbandfec=1
|
||||||
|
a=rtpmap:63 red/48000/2
|
||||||
|
a=fmtp:63 111/111
|
||||||
|
a=rtpmap:9 G722/8000
|
||||||
|
a=rtpmap:102 ILBC/8000
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
a=rtpmap:8 PCMA/8000
|
||||||
|
a=rtpmap:13 CN/8000
|
||||||
|
a=rtpmap:110 telephone-event/48000
|
||||||
|
a=rtpmap:126 telephone-event/8000
|
||||||
|
a=ssrc:2860285610 cname:2EW1hNfQMKxwbRrt
|
||||||
|
a=ssrc:2860285610 msid:- ef1bcbd2-7e69-40d3-9532-0f4a698022a7
|
||||||
|
m=video 9 UDP/TLS/RTP/SAVPF 96 97 39 40 98 99 127 103 104 105 106 107 108
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:H2Ms
|
||||||
|
a=ice-pwd:14ODtTVh5+lT7W0+g9EAlE4j
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 47:81:90:07:43:95:D7:F2:DA:60:DA:79:E5:88:26:65:29:4A:26:28:7A:B7:AB:D3:DB:CE:C9:09:39:EB:31:91
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:1
|
||||||
|
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:13 urn:3gpp:video-orientation
|
||||||
|
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
|
||||||
|
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
|
||||||
|
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
|
||||||
|
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
|
||||||
|
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
|
||||||
|
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
|
||||||
|
a=sendonly
|
||||||
|
a=msid:- 8b57ef63-835d-4acf-bce9-18e26cebf9b1
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtcp-rsize
|
||||||
|
a=rtpmap:96 VP8/90000
|
||||||
|
a=rtcp-fb:96 goog-remb
|
||||||
|
a=rtcp-fb:96 transport-cc
|
||||||
|
a=rtcp-fb:96 ccm fir
|
||||||
|
a=rtcp-fb:96 nack
|
||||||
|
a=rtcp-fb:96 nack pli
|
||||||
|
a=rtpmap:97 rtx/90000
|
||||||
|
a=fmtp:97 apt=96
|
||||||
|
a=rtpmap:39 AV1/90000
|
||||||
|
a=rtcp-fb:39 goog-remb
|
||||||
|
a=rtcp-fb:39 transport-cc
|
||||||
|
a=rtcp-fb:39 ccm fir
|
||||||
|
a=rtcp-fb:39 nack
|
||||||
|
a=rtcp-fb:39 nack pli
|
||||||
|
a=rtpmap:40 rtx/90000
|
||||||
|
a=fmtp:40 apt=39
|
||||||
|
a=rtpmap:98 VP9/90000
|
||||||
|
a=rtcp-fb:98 goog-remb
|
||||||
|
a=rtcp-fb:98 transport-cc
|
||||||
|
a=rtcp-fb:98 ccm fir
|
||||||
|
a=rtcp-fb:98 nack
|
||||||
|
a=rtcp-fb:98 nack pli
|
||||||
|
a=fmtp:98 profile-id=0
|
||||||
|
a=rtpmap:99 rtx/90000
|
||||||
|
a=fmtp:99 apt=98
|
||||||
|
a=rtpmap:127 H264/90000
|
||||||
|
a=rtcp-fb:127 goog-remb
|
||||||
|
a=rtcp-fb:127 transport-cc
|
||||||
|
a=rtcp-fb:127 ccm fir
|
||||||
|
a=rtcp-fb:127 nack
|
||||||
|
a=rtcp-fb:127 nack pli
|
||||||
|
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
|
||||||
|
a=rtpmap:103 rtx/90000
|
||||||
|
a=fmtp:103 apt=127
|
||||||
|
a=rtpmap:104 H265/90000
|
||||||
|
a=rtcp-fb:104 goog-remb
|
||||||
|
a=rtcp-fb:104 transport-cc
|
||||||
|
a=rtcp-fb:104 ccm fir
|
||||||
|
a=rtcp-fb:104 nack
|
||||||
|
a=rtcp-fb:104 nack pli
|
||||||
|
a=rtpmap:105 rtx/90000
|
||||||
|
a=fmtp:105 apt=104
|
||||||
|
a=rtpmap:106 red/90000
|
||||||
|
a=rtpmap:107 rtx/90000
|
||||||
|
a=fmtp:107 apt=106
|
||||||
|
a=rtpmap:108 ulpfec/90000
|
||||||
|
a=ssrc-group:FID 100166069 2038394461
|
||||||
|
a=ssrc:100166069 cname:2EW1hNfQMKxwbRrt
|
||||||
|
a=ssrc:100166069 msid:- 8b57ef63-835d-4acf-bce9-18e26cebf9b1
|
||||||
|
a=ssrc:2038394461 cname:2EW1hNfQMKxwbRrt
|
||||||
|
a=ssrc:2038394461 msid:- 8b57ef63-835d-4acf-bce9-18e26cebf9b1
|
||||||
|
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:H2Ms
|
||||||
|
a=ice-pwd:14ODtTVh5+lT7W0+g9EAlE4j
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 47:81:90:07:43:95:D7:F2:DA:60:DA:79:E5:88:26:65:29:4A:26:28:7A:B7:AB:D3:DB:CE:C9:09:39:EB:31:91
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:2
|
||||||
|
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=sendonly
|
||||||
|
a=msid:- 49d08cb1-a325-4a5f-805a-72a215eb67af
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtpmap:111 opus/48000/2
|
||||||
|
a=rtcp-fb:111 transport-cc
|
||||||
|
a=fmtp:111 minptime=10;useinbandfec=1
|
||||||
|
a=rtpmap:63 red/48000/2
|
||||||
|
a=fmtp:63 111/111
|
||||||
|
a=rtpmap:9 G722/8000
|
||||||
|
a=rtpmap:102 ILBC/8000
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
a=rtpmap:8 PCMA/8000
|
||||||
|
a=rtpmap:13 CN/8000
|
||||||
|
a=rtpmap:110 telephone-event/48000
|
||||||
|
a=rtpmap:126 telephone-event/8000
|
||||||
|
a=ssrc:2666757999 cname:2EW1hNfQMKxwbRrt
|
||||||
|
a=ssrc:2666757999 msid:- 49d08cb1-a325-4a5f-805a-72a215eb67af
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
v=0
|
||||||
|
o=- 6005790964057401669 2 IN IP4 127.0.0.1
|
||||||
|
s=-
|
||||||
|
t=0 0
|
||||||
|
a=group:BUNDLE 0 1
|
||||||
|
a=extmap-allow-mixed
|
||||||
|
a=msid-semantic: WMS ARDAMS
|
||||||
|
m=video 9 UDP/TLS/RTP/SAVPF 96 97 39 40 98 99 127 103 104 105 106 107 108
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:UITA
|
||||||
|
a=ice-pwd:obg6A6ZHKhr5CGzmmgRfTk/y
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 5E:23:E2:B2:0F:ED:FC:A2:20:06:24:0F:6A:4B:99:33:91:39:A7:40:A5:20:88:77:D6:99:04:FB:C7:CD:7F:33
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:0
|
||||||
|
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:3 urn:3gpp:video-orientation
|
||||||
|
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
|
||||||
|
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
|
||||||
|
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
|
||||||
|
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
|
||||||
|
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
|
||||||
|
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
|
||||||
|
a=sendrecv
|
||||||
|
a=msid:ARDAMS ARDAMSv0
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtcp-rsize
|
||||||
|
a=rtpmap:96 VP8/90000
|
||||||
|
a=rtcp-fb:96 goog-remb
|
||||||
|
a=rtcp-fb:96 transport-cc
|
||||||
|
a=rtcp-fb:96 ccm fir
|
||||||
|
a=rtcp-fb:96 nack
|
||||||
|
a=rtcp-fb:96 nack pli
|
||||||
|
a=rtpmap:97 rtx/90000
|
||||||
|
a=fmtp:97 apt=96
|
||||||
|
a=rtpmap:39 AV1/90000
|
||||||
|
a=rtcp-fb:39 goog-remb
|
||||||
|
a=rtcp-fb:39 transport-cc
|
||||||
|
a=rtcp-fb:39 ccm fir
|
||||||
|
a=rtcp-fb:39 nack
|
||||||
|
a=rtcp-fb:39 nack pli
|
||||||
|
a=rtpmap:40 rtx/90000
|
||||||
|
a=fmtp:40 apt=39
|
||||||
|
a=rtpmap:98 VP9/90000
|
||||||
|
a=rtcp-fb:98 goog-remb
|
||||||
|
a=rtcp-fb:98 transport-cc
|
||||||
|
a=rtcp-fb:98 ccm fir
|
||||||
|
a=rtcp-fb:98 nack
|
||||||
|
a=rtcp-fb:98 nack pli
|
||||||
|
a=fmtp:98 profile-id=0
|
||||||
|
a=rtpmap:99 rtx/90000
|
||||||
|
a=fmtp:99 apt=98
|
||||||
|
a=rtpmap:127 H264/90000
|
||||||
|
a=rtcp-fb:127 goog-remb
|
||||||
|
a=rtcp-fb:127 transport-cc
|
||||||
|
a=rtcp-fb:127 ccm fir
|
||||||
|
a=rtcp-fb:127 nack
|
||||||
|
a=rtcp-fb:127 nack pli
|
||||||
|
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
|
||||||
|
a=rtpmap:103 rtx/90000
|
||||||
|
a=fmtp:103 apt=127
|
||||||
|
a=rtpmap:104 H265/90000
|
||||||
|
a=rtcp-fb:104 goog-remb
|
||||||
|
a=rtcp-fb:104 transport-cc
|
||||||
|
a=rtcp-fb:104 ccm fir
|
||||||
|
a=rtcp-fb:104 nack
|
||||||
|
a=rtcp-fb:104 nack pli
|
||||||
|
a=rtpmap:105 rtx/90000
|
||||||
|
a=fmtp:105 apt=104
|
||||||
|
a=rtpmap:106 red/90000
|
||||||
|
a=rtpmap:107 rtx/90000
|
||||||
|
a=fmtp:107 apt=106
|
||||||
|
a=rtpmap:108 ulpfec/90000
|
||||||
|
a=ssrc-group:FID 1882091013 3163545249
|
||||||
|
a=ssrc:1882091013 cname:L6diPFsW7sR8uU/a
|
||||||
|
a=ssrc:1882091013 msid:ARDAMS ARDAMSv0
|
||||||
|
a=ssrc:3163545249 cname:L6diPFsW7sR8uU/a
|
||||||
|
a=ssrc:3163545249 msid:ARDAMS ARDAMSv0
|
||||||
|
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:UITA
|
||||||
|
a=ice-pwd:obg6A6ZHKhr5CGzmmgRfTk/y
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 5E:23:E2:B2:0F:ED:FC:A2:20:06:24:0F:6A:4B:99:33:91:39:A7:40:A5:20:88:77:D6:99:04:FB:C7:CD:7F:33
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:1
|
||||||
|
a=extmap:14 urn:ietf:params:rtp-hdrext:ssrc-audio-level
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=sendrecv
|
||||||
|
a=msid:ARDAMS ARDAMSa0
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtpmap:111 opus/48000/2
|
||||||
|
a=rtcp-fb:111 transport-cc
|
||||||
|
a=fmtp:111 minptime=10;useinbandfec=1
|
||||||
|
a=rtpmap:63 red/48000/2
|
||||||
|
a=fmtp:63 111/111
|
||||||
|
a=rtpmap:9 G722/8000
|
||||||
|
a=rtpmap:102 ILBC/8000
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
a=rtpmap:8 PCMA/8000
|
||||||
|
a=rtpmap:13 CN/8000
|
||||||
|
a=rtpmap:110 telephone-event/48000
|
||||||
|
a=rtpmap:126 telephone-event/8000
|
||||||
|
a=ssrc:1776947399 cname:L6diPFsW7sR8uU/a
|
||||||
|
a=ssrc:1776947399 msid:ARDAMS ARDAMSa0
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
v=0
|
||||||
|
o=- 2629706501878304631 2 IN IP4 127.0.0.1
|
||||||
|
s=-
|
||||||
|
t=0 0
|
||||||
|
a=group:BUNDLE 0 1
|
||||||
|
a=extmap-allow-mixed
|
||||||
|
a=msid-semantic: WMS ARDAMS
|
||||||
|
m=video 9 UDP/TLS/RTP/SAVPF 96 97 39 40 98 99 127 103 104 105 106 107 108 43
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:+zOA
|
||||||
|
a=ice-pwd:q88Il7adjqdu6SeSqAdsv8lv
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 8D:0B:86:0B:8C:DF:22:99:85:DD:60:41:AA:FE:F1:98:FE:FB:29:32:5C:11:6E:47:54:82:21:6C:A0:4F:60:B2
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:0
|
||||||
|
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:3 urn:3gpp:video-orientation
|
||||||
|
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
|
||||||
|
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
|
||||||
|
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
|
||||||
|
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
|
||||||
|
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
|
||||||
|
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
|
||||||
|
a=sendrecv
|
||||||
|
a=msid:ARDAMS ARDAMSv0
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtcp-rsize
|
||||||
|
a=rtpmap:96 VP8/90000
|
||||||
|
a=rtcp-fb:96 goog-remb
|
||||||
|
a=rtcp-fb:96 transport-cc
|
||||||
|
a=rtcp-fb:96 ccm fir
|
||||||
|
a=rtcp-fb:96 nack
|
||||||
|
a=rtcp-fb:96 nack pli
|
||||||
|
a=rtpmap:97 rtx/90000
|
||||||
|
a=fmtp:97 apt=96
|
||||||
|
a=rtpmap:39 AV1/90000
|
||||||
|
a=rtcp-fb:39 goog-remb
|
||||||
|
a=rtcp-fb:39 transport-cc
|
||||||
|
a=rtcp-fb:39 ccm fir
|
||||||
|
a=rtcp-fb:39 nack
|
||||||
|
a=rtcp-fb:39 nack pli
|
||||||
|
a=rtpmap:40 rtx/90000
|
||||||
|
a=fmtp:40 apt=39
|
||||||
|
a=rtpmap:98 VP9/90000
|
||||||
|
a=rtcp-fb:98 goog-remb
|
||||||
|
a=rtcp-fb:98 transport-cc
|
||||||
|
a=rtcp-fb:98 ccm fir
|
||||||
|
a=rtcp-fb:98 nack
|
||||||
|
a=rtcp-fb:98 nack pli
|
||||||
|
a=fmtp:98 profile-id=0
|
||||||
|
a=rtpmap:99 rtx/90000
|
||||||
|
a=fmtp:99 apt=98
|
||||||
|
a=rtpmap:127 H264/90000
|
||||||
|
a=rtcp-fb:127 goog-remb
|
||||||
|
a=rtcp-fb:127 transport-cc
|
||||||
|
a=rtcp-fb:127 ccm fir
|
||||||
|
a=rtcp-fb:127 nack
|
||||||
|
a=rtcp-fb:127 nack pli
|
||||||
|
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
|
||||||
|
a=rtpmap:103 rtx/90000
|
||||||
|
a=fmtp:103 apt=127
|
||||||
|
a=rtpmap:104 H265/90000
|
||||||
|
a=rtcp-fb:104 goog-remb
|
||||||
|
a=rtcp-fb:104 transport-cc
|
||||||
|
a=rtcp-fb:104 ccm fir
|
||||||
|
a=rtcp-fb:104 nack
|
||||||
|
a=rtcp-fb:104 nack pli
|
||||||
|
a=rtpmap:105 rtx/90000
|
||||||
|
a=fmtp:105 apt=104
|
||||||
|
a=rtpmap:106 red/90000
|
||||||
|
a=rtpmap:107 rtx/90000
|
||||||
|
a=fmtp:107 apt=106
|
||||||
|
a=rtpmap:108 ulpfec/90000
|
||||||
|
a=rtpmap:43 flexfec-03/90000
|
||||||
|
a=rtcp-fb:43 goog-remb
|
||||||
|
a=rtcp-fb:43 transport-cc
|
||||||
|
a=fmtp:43 repair-window=10000000
|
||||||
|
a=ssrc-group:FID 129065984 1082217256
|
||||||
|
a=ssrc-group:FEC-FR 129065984 4071693473
|
||||||
|
a=ssrc:129065984 cname:T1fpJkmBNuVUtXM8
|
||||||
|
a=ssrc:129065984 msid:ARDAMS ARDAMSv0
|
||||||
|
a=ssrc:1082217256 cname:T1fpJkmBNuVUtXM8
|
||||||
|
a=ssrc:1082217256 msid:ARDAMS ARDAMSv0
|
||||||
|
a=ssrc:4071693473 cname:T1fpJkmBNuVUtXM8
|
||||||
|
a=ssrc:4071693473 msid:ARDAMS ARDAMSv0
|
||||||
|
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126
|
||||||
|
c=IN IP4 0.0.0.0
|
||||||
|
a=rtcp:9 IN IP4 0.0.0.0
|
||||||
|
a=ice-ufrag:+zOA
|
||||||
|
a=ice-pwd:q88Il7adjqdu6SeSqAdsv8lv
|
||||||
|
a=ice-options:trickle renomination
|
||||||
|
a=fingerprint:sha-256 8D:0B:86:0B:8C:DF:22:99:85:DD:60:41:AA:FE:F1:98:FE:FB:29:32:5C:11:6E:47:54:82:21:6C:A0:4F:60:B2
|
||||||
|
a=setup:actpass
|
||||||
|
a=mid:1
|
||||||
|
a=extmap:14 urn:ietf:params:rtp-hdrext:ssrc-audio-level
|
||||||
|
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
|
||||||
|
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
|
||||||
|
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
|
||||||
|
a=sendrecv
|
||||||
|
a=msid:ARDAMS ARDAMSa0
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtpmap:111 opus/48000/2
|
||||||
|
a=rtcp-fb:111 transport-cc
|
||||||
|
a=fmtp:111 minptime=10;useinbandfec=1
|
||||||
|
a=rtpmap:63 red/48000/2
|
||||||
|
a=fmtp:63 111/111
|
||||||
|
a=rtpmap:9 G722/8000
|
||||||
|
a=rtpmap:102 ILBC/8000
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
a=rtpmap:8 PCMA/8000
|
||||||
|
a=rtpmap:13 CN/8000
|
||||||
|
a=rtpmap:110 telephone-event/48000
|
||||||
|
a=rtpmap:126 telephone-event/8000
|
||||||
|
a=ssrc:2019904101 cname:T1fpJkmBNuVUtXM8
|
||||||
|
a=ssrc:2019904101 msid:ARDAMS ARDAMSa0
|
||||||
|
|
@ -12,5 +12,12 @@
|
||||||
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
|
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
|
||||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<service android:name="com.zlm.rtc.push.ScreenShareService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true"
|
||||||
|
android:foregroundServiceType="mediaProjection"/>
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
@ -1,9 +1,14 @@
|
||||||
package com.zlm.rtc
|
package com.zlm.rtc
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
import com.zlm.rtc.push.PushMode
|
||||||
|
import org.webrtc.SurfaceViewRenderer
|
||||||
|
|
||||||
abstract class ZLMRTCPusher {
|
abstract class ZLMRTCPusher {
|
||||||
abstract fun push(app: String, streamId: String)
|
|
||||||
|
public abstract fun bind(surface: SurfaceViewRenderer, localPreview: Boolean)
|
||||||
|
|
||||||
|
abstract fun push(app: String, streamId: String, mode: PushMode = PushMode.CAMERA)
|
||||||
|
|
||||||
abstract fun stop()
|
abstract fun stop()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.zlm.rtc.base;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
|
||||||
|
public class ActivityLauncher {
|
||||||
|
private static final String TAG = "ActivityLauncher";
|
||||||
|
private Context mContext;
|
||||||
|
private RouterFragment mRouterFragment;
|
||||||
|
|
||||||
|
public static ActivityLauncher init(FragmentActivity activity) {
|
||||||
|
return new ActivityLauncher(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ActivityLauncher(FragmentActivity activity) {
|
||||||
|
mContext = activity;
|
||||||
|
mRouterFragment = getRouterFragment(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RouterFragment getRouterFragment(FragmentActivity activity) {
|
||||||
|
RouterFragment routerFragment = findRouterFragment(activity);
|
||||||
|
if (routerFragment == null) {
|
||||||
|
routerFragment = RouterFragment.newInstance();
|
||||||
|
FragmentManager fragmentManager = activity.getSupportFragmentManager();
|
||||||
|
fragmentManager
|
||||||
|
.beginTransaction()
|
||||||
|
.add(routerFragment, TAG)
|
||||||
|
.commitAllowingStateLoss();
|
||||||
|
fragmentManager.executePendingTransactions();
|
||||||
|
}
|
||||||
|
return routerFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RouterFragment findRouterFragment(FragmentActivity activity) {
|
||||||
|
return (RouterFragment) activity.getSupportFragmentManager().findFragmentByTag(TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startActivityForResult(Class<?> clazz, Callback callback) {
|
||||||
|
Intent intent = new Intent(mContext, clazz);
|
||||||
|
startActivityForResult(intent, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startActivityForResult(Intent intent, Callback callback) {
|
||||||
|
mRouterFragment.startActivityForResult(intent, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Callback {
|
||||||
|
void onActivityResult(int resultCode, Intent data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.zlm.rtc.base;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class RouterFragment extends Fragment {
|
||||||
|
|
||||||
|
private SparseArray<ActivityLauncher.Callback> mCallbacks = new SparseArray<>();
|
||||||
|
private Random mCodeGenerator = new Random();
|
||||||
|
|
||||||
|
public RouterFragment() {
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RouterFragment newInstance() {
|
||||||
|
return new RouterFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setRetainInstance(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startActivityForResult(Intent intent, ActivityLauncher.Callback callback) {
|
||||||
|
int requestCode = makeRequestCode();
|
||||||
|
mCallbacks.put(requestCode, callback);
|
||||||
|
startActivityForResult(intent, requestCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 随机生成唯一的requestCode,最多尝试10次
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int makeRequestCode() {
|
||||||
|
int requestCode;
|
||||||
|
int tryCount = 0;
|
||||||
|
do {
|
||||||
|
requestCode = mCodeGenerator.nextInt(0x0000FFFF);
|
||||||
|
tryCount++;
|
||||||
|
} while (mCallbacks.indexOfKey(requestCode) >= 0 && tryCount < 10);
|
||||||
|
return requestCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
ActivityLauncher.Callback callback = mCallbacks.get(requestCode);
|
||||||
|
mCallbacks.remove(requestCode);
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onActivityResult(resultCode, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -636,7 +636,7 @@ public class PeerConnectionClient {
|
||||||
// Create SDP constraints.
|
// Create SDP constraints.
|
||||||
sdpMediaConstraints = new MediaConstraints();
|
sdpMediaConstraints = new MediaConstraints();
|
||||||
sdpMediaConstraints.mandatory.add(
|
sdpMediaConstraints.mandatory.add(
|
||||||
new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
|
new MediaConstraints.KeyValuePair("OfferToReceiveAudio", Boolean.toString(true)));
|
||||||
sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair(
|
sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair(
|
||||||
"OfferToReceiveVideo", Boolean.toString(true)));//这里
|
"OfferToReceiveVideo", Boolean.toString(true)));//这里
|
||||||
}
|
}
|
||||||
|
|
@ -692,8 +692,10 @@ public class PeerConnectionClient {
|
||||||
|
|
||||||
if (saveVideoFileRecorder == null) {
|
if (saveVideoFileRecorder == null) {
|
||||||
saveVideoFileRecorder = new VideoFileRecorder();
|
saveVideoFileRecorder = new VideoFileRecorder();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// peerConnection.addTransceiver(MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO,new RtpTransceiver.RtpTransceiverInit(RtpTransceiver.RtpTransceiverDirection.SEND_RECV));
|
||||||
|
// peerConnection.addTransceiver(MediaStreamTrack.MediaType.MEDIA_TYPE_VIDEO,new RtpTransceiver.RtpTransceiverInit(RtpTransceiver.RtpTransceiverDirection.SEND_RECV));
|
||||||
|
|
||||||
Log.d(TAG, "Peer connection created.");
|
Log.d(TAG, "Peer connection created.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.zlm.rtc.push
|
||||||
|
|
||||||
|
enum class PushMode {
|
||||||
|
CAMERA, SCREEN, FILE
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.zlm.rtc.push
|
||||||
|
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.Service
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.media.projection.MediaProjectionManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.IBinder
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import com.zlm.rtc.R
|
||||||
|
|
||||||
|
class ScreenShareService :Service(){
|
||||||
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
val resultCode = intent?.getIntExtra("resultCode", -1)
|
||||||
|
val resultData = intent?.getParcelableExtra<Intent>("data")
|
||||||
|
createNotificationChannel()
|
||||||
|
|
||||||
|
resultCode?.let {code->
|
||||||
|
resultData?.let { data->
|
||||||
|
val mediaProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
|
||||||
|
val mediaProjection = mediaProjectionManager.getMediaProjection(code, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return super.onStartCommand(intent, flags, startId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private fun createNotificationChannel() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val channel = NotificationChannel(
|
||||||
|
"ScreenShared", "屏幕录制",
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT
|
||||||
|
)
|
||||||
|
val manager = getSystemService(
|
||||||
|
NotificationManager::class.java
|
||||||
|
)
|
||||||
|
manager.createNotificationChannel(channel)
|
||||||
|
}
|
||||||
|
|
||||||
|
val notification = NotificationCompat.Builder(this, "ScreenShared")
|
||||||
|
.setContentTitle("屏幕分享")
|
||||||
|
.setContentText("分享中...")
|
||||||
|
.setSmallIcon(R.drawable.icon_screen_share)
|
||||||
|
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.icon_screen_share))
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build()
|
||||||
|
startForeground(1024, notification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,16 @@
|
||||||
package com.zlm.rtc.push
|
package com.zlm.rtc.push
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.content.Intent
|
||||||
import android.media.AudioManager
|
import android.media.projection.MediaProjection
|
||||||
|
import android.media.projection.MediaProjectionManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
import com.zlm.rtc.NativeLib
|
import com.zlm.rtc.NativeLib
|
||||||
import com.zlm.rtc.ZLMRTCPusher
|
import com.zlm.rtc.ZLMRTCPusher
|
||||||
|
import com.zlm.rtc.base.ActivityLauncher
|
||||||
import com.zlm.rtc.client.HttpClient
|
import com.zlm.rtc.client.HttpClient
|
||||||
import com.zlm.rtc.client.PeerConnectionClient
|
import com.zlm.rtc.client.PeerConnectionClient
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
@ -15,6 +20,7 @@ import org.webrtc.CameraEnumerator
|
||||||
import org.webrtc.EglBase
|
import org.webrtc.EglBase
|
||||||
import org.webrtc.IceCandidate
|
import org.webrtc.IceCandidate
|
||||||
import org.webrtc.PeerConnectionFactory
|
import org.webrtc.PeerConnectionFactory
|
||||||
|
import org.webrtc.ScreenCapturerAndroid
|
||||||
import org.webrtc.SessionDescription
|
import org.webrtc.SessionDescription
|
||||||
import org.webrtc.StatsReport
|
import org.webrtc.StatsReport
|
||||||
import org.webrtc.SurfaceViewRenderer
|
import org.webrtc.SurfaceViewRenderer
|
||||||
|
|
@ -22,7 +28,7 @@ import org.webrtc.VideoCapturer
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
class ZLMRTCPusherImpl(val context: FragmentActivity) : ZLMRTCPusher(),
|
||||||
PeerConnectionClient.PeerConnectionEvents {
|
PeerConnectionClient.PeerConnectionEvents {
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,6 +45,10 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
private var app: String = ""
|
private var app: String = ""
|
||||||
private var streamId: String = ""
|
private var streamId: String = ""
|
||||||
|
|
||||||
|
|
||||||
|
private val CAPTURE_PERMISSION_REQUEST_CODE = 1
|
||||||
|
|
||||||
|
|
||||||
private fun initPeerConnectionClient(): PeerConnectionClient {
|
private fun initPeerConnectionClient(): PeerConnectionClient {
|
||||||
eglBase = EglBase.create()
|
eglBase = EglBase.create()
|
||||||
return PeerConnectionClient(
|
return PeerConnectionClient(
|
||||||
|
|
@ -47,19 +57,19 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
1280,
|
0,
|
||||||
720,
|
0,
|
||||||
defaultFps,
|
0,
|
||||||
1024 * 1000 * 2,
|
0,
|
||||||
"H264",
|
"VP8",
|
||||||
true,
|
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
0,
|
0,
|
||||||
"OPUS",
|
"OPUS",
|
||||||
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
true,
|
||||||
false,
|
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
|
@ -74,6 +84,18 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
} else {
|
} else {
|
||||||
createCameraCapture(Camera1Enumerator(true))
|
createCameraCapture(Camera1Enumerator(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return videoCapturer
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun createScreenCapture(context: Context?): VideoCapturer? {
|
||||||
|
val videoCapturer: VideoCapturer? = if (Camera2Enumerator.isSupported(context)) {
|
||||||
|
createCameraCapture(Camera2Enumerator(context))
|
||||||
|
} else {
|
||||||
|
createCameraCapture(Camera1Enumerator(true))
|
||||||
|
}
|
||||||
|
|
||||||
return videoCapturer
|
return videoCapturer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +135,12 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun push(app: String, streamId: String) {
|
override fun bind(surface: SurfaceViewRenderer, localPreview: Boolean) {
|
||||||
|
this.surfaceViewRenderer = surface
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun push(app: String, streamId: String, mode: PushMode) {
|
||||||
this.app = app
|
this.app = app
|
||||||
this.streamId = streamId
|
this.streamId = streamId
|
||||||
if (peerConnectionClient == null) peerConnectionClient = initPeerConnectionClient()
|
if (peerConnectionClient == null) peerConnectionClient = initPeerConnectionClient()
|
||||||
|
|
@ -121,10 +148,41 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
peerConnectionClient?.setAudioEnabled(true)
|
peerConnectionClient?.setAudioEnabled(true)
|
||||||
peerConnectionClient?.setVideoEnabled(true)
|
peerConnectionClient?.setVideoEnabled(true)
|
||||||
peerConnectionClient?.createPeerConnectionFactory(PeerConnectionFactory.Options())
|
peerConnectionClient?.createPeerConnectionFactory(PeerConnectionFactory.Options())
|
||||||
|
|
||||||
|
if (mode == PushMode.CAMERA) {
|
||||||
peerConnectionClient?.createPeerConnection(createVideoCapture(context), localHandleId)
|
peerConnectionClient?.createPeerConnection(createVideoCapture(context), localHandleId)
|
||||||
peerConnectionClient?.createOffer(localHandleId)
|
peerConnectionClient?.createOffer(localHandleId)
|
||||||
|
|
||||||
|
} else if (mode == PushMode.SCREEN) {
|
||||||
|
|
||||||
|
val mediaProjectionManager = context.getSystemService(
|
||||||
|
Context.MEDIA_PROJECTION_SERVICE
|
||||||
|
) as MediaProjectionManager
|
||||||
|
|
||||||
|
ActivityLauncher.init(context).startActivityForResult(
|
||||||
|
mediaProjectionManager.createScreenCaptureIntent()
|
||||||
|
) { resultCode, data ->
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
|
||||||
|
ContextCompat.startForegroundService(context, Intent(context, ScreenShareService::class.java))
|
||||||
|
|
||||||
|
val screenCapturerAndroid =
|
||||||
|
ScreenCapturerAndroid(data, object : MediaProjection.Callback() {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
peerConnectionClient?.createPeerConnection(screenCapturerAndroid, localHandleId)
|
||||||
|
peerConnectionClient?.createOffer(localHandleId)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun stop() {
|
override fun stop() {
|
||||||
surfaceViewRenderer?.clearImage()
|
surfaceViewRenderer?.clearImage()
|
||||||
|
|
@ -144,6 +202,7 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
mutableMapOf()
|
mutableMapOf()
|
||||||
)
|
)
|
||||||
val result = JSONObject(doPost)
|
val result = JSONObject(doPost)
|
||||||
|
logger(result.toString())
|
||||||
val code = result.getInt("code")
|
val code = result.getInt("code")
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
logger("handleId: $doPost")
|
logger("handleId: $doPost")
|
||||||
|
|
@ -155,11 +214,12 @@ class ZLMRTCPusherImpl(val context:Context) :ZLMRTCPusher(),
|
||||||
} else {
|
} else {
|
||||||
val msg = result.getString("msg")
|
val msg = result.getString("msg")
|
||||||
logger("handleId: $msg")
|
logger("handleId: $msg")
|
||||||
|
peerConnectionClient?.setAudioEnabled(false)
|
||||||
|
peerConnectionClient?.setVideoEnabled(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIceCandidate(handleId: BigInteger?, candidate: IceCandidate?) {
|
override fun onIceCandidate(handleId: BigInteger?, candidate: IceCandidate?) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIceCandidatesRemoved(
|
override fun onIceCandidatesRemoved(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<vector android:height="24dp" android:viewportHeight="1024"
|
||||||
|
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#333333" android:pathData="M740.4,709.3H298.7a98.2,98.2 0,0 1,-98.1 -98.1V360.2A98.2,98.2 0,0 1,298.7 262.1h426.7a98.2,98.2 0,0 1,98.1 98.1v266a12.8,12.8 0,0 1,-25.6 0V360.2a72.6,72.6 0,0 0,-72.5 -72.5H298.7a72.6,72.6 0,0 0,-72.5 72.5v251a72.6,72.6 0,0 0,72.5 72.5h441.7a12.8,12.8 0,0 1,0 25.6zM612.2,761.9H401.1a12.8,12.8 0,1 1,0 -25.6h211.1a12.8,12.8 0,0 1,0 25.6z"/>
|
||||||
|
<path android:fillColor="#0098F0" android:pathData="M649.2,483.3L531.6,390v54.8c-147,0.7 -156.8,136.5 -156.8,136.5 49,-68.3 156.8,-58.9 156.8,-58.9v54.3z"/>
|
||||||
|
</vector>
|
||||||
Loading…
Reference in New Issue