mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 22:55:52 +08:00
桌面推流ok
This commit is contained in:
parent
bebeee07d3
commit
31264e4cf4
@ -25,7 +25,7 @@ class PlayerDemoActivity : AppCompatActivity() {
|
|||||||
//ffmpeg -re -stream_loop -1 -i "D:\li\hot\data\data\baseline.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp -bf 0 rtsp://zlmediakit.com/live/li
|
//ffmpeg -re -stream_loop -1 -i "D:\li\hot\data\data\baseline.mp4" -vcodec h264 -acodec aac -f rtsp -rtsp_transport tcp -bf 0 rtsp://zlmediakit.com/live/li
|
||||||
//ffmpeg -re -stream_loop -1 -i "D:\li\hot\data\data\test.mp4" -vcodec h264 -acodec aac -f flv -bf 0 rtmp://zlmediakit.com/live/li
|
//ffmpeg -re -stream_loop -1 -i "D:\li\hot\data\data\test.mp4" -vcodec h264 -acodec aac -f flv -bf 0 rtmp://zlmediakit.com/live/li
|
||||||
|
|
||||||
player.bind(surface_view_renderer, false)
|
player.bind(surface_view_renderer)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +65,6 @@ class PlayerDemoActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onVolume(view: View) {
|
fun onVolume(view: View) {
|
||||||
player.setSpeakerphoneOn(true)
|
player.setVolume()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -62,7 +62,18 @@ class PusherDemoActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onPushFile(view: View) {
|
fun onPushFile(view: View) {
|
||||||
|
PermissionX.init(this)
|
||||||
|
.permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
.request { allGranted, grantedList, deniedList ->
|
||||||
|
if (allGranted) {
|
||||||
|
pusher.push(
|
||||||
|
tv_app.text.toString(),
|
||||||
|
tv_stream_id.text.toString(),
|
||||||
|
PushMode.FILE,
|
||||||
|
""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
76
webrtc_player/android/play.sdp
Normal file
76
webrtc_player/android/play.sdp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
v=0
|
||||||
|
o=- 5986549880880292178 2 IN IP4 108.181.24.73
|
||||||
|
s=-
|
||||||
|
t=0 0
|
||||||
|
a=group:BUNDLE 0 1
|
||||||
|
a=msid-semantic: WMS ARDAMS
|
||||||
|
a=ice-lite
|
||||||
|
m=audio 8000 UDP/TLS/RTP/SAVPF 111
|
||||||
|
c=IN IP4 108.181.24.73
|
||||||
|
a=rtcp:8000 IN IP4 108.181.24.73
|
||||||
|
a=ice-ufrag:bLUYSR9AH0A=_2105
|
||||||
|
a=ice-pwd:wstnRIopRDwBZyv56AZlGuOm
|
||||||
|
a=ice-options:trickle
|
||||||
|
a=fingerprint:sha-256 F4:C9:0C:ED:05:93:C0:F9:AC:34:71:60:2D:3E:D0:47:91:CC:FD:38:C7:63:4A:93:C3:48:0C:B4:6F:32:76:FE
|
||||||
|
a=setup:passive
|
||||||
|
a=mid:0
|
||||||
|
a=ice-lite
|
||||||
|
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=inactive
|
||||||
|
a=rtcp-mux
|
||||||
|
a=rtpmap:111 opus/48000/2
|
||||||
|
a=rtcp-fb:111 transport-cc
|
||||||
|
a=fmtp:111 minptime=10;useinbandfec=1
|
||||||
|
a=msid:zlmediakit-mslabel zlmediakit-label-0
|
||||||
|
a=ssrc:2 cname:zlmediakit-rtp
|
||||||
|
a=ssrc:2 msid:zlmediakit-mslabel zlmediakit-label-0
|
||||||
|
a=ssrc:2 mslabel:zlmediakit-mslabel
|
||||||
|
a=ssrc:2 label:zlmediakit-label-0
|
||||||
|
a=candidate:udpcandidate 1 udp 110 108.181.24.73 8000 typ host
|
||||||
|
a=candidate:tcpcandidate 1 tcp 105 108.181.24.73 8000 typ host tcptype passive
|
||||||
|
|
||||||
|
|
||||||
|
m=video 8000 UDP/TLS/RTP/SAVPF 127 103
|
||||||
|
c=IN IP4 108.181.24.73
|
||||||
|
a=rtcp:8000 IN IP4 108.181.24.73
|
||||||
|
a=ice-ufrag:bLUYSR9AH0A=_2105
|
||||||
|
a=ice-pwd:wstnRIopRDwBZyv56AZlGuOm
|
||||||
|
a=ice-options:trickle
|
||||||
|
a=fingerprint:sha-256 F4:C9:0C:ED:05:93:C0:F9:AC:34:71:60:2D:3E:D0:47:91:CC:FD:38:C7:63:4A:93:C3:48:0C:B4:6F:32:76:FE
|
||||||
|
a=setup:passive
|
||||||
|
a=mid:1
|
||||||
|
a=ice-lite
|
||||||
|
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
|
||||||
|
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: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: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=rtcp-mux
|
||||||
|
a=rtpmap:127 H264/90000
|
||||||
|
a=rtcp-fb:127 ccm fir
|
||||||
|
a=rtcp-fb:127 goog-remb
|
||||||
|
a=rtcp-fb:127 nack
|
||||||
|
a=rtcp-fb:127 nack pli
|
||||||
|
a=rtcp-fb:127 transport-cc
|
||||||
|
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=msid:zlmediakit-mslabel zlmediakit-label-1
|
||||||
|
a=ssrc:1 cname:zlmediakit-rtp
|
||||||
|
a=ssrc:1 msid:zlmediakit-mslabel zlmediakit-label-1
|
||||||
|
a=ssrc:1 mslabel:zlmediakit-mslabel
|
||||||
|
a=ssrc:1 label:zlmediakit-label-1
|
||||||
|
a=ssrc:3 cname:zlmediakit-rtp
|
||||||
|
a=ssrc:3 msid:zlmediakit-mslabel zlmediakit-label-1
|
||||||
|
a=ssrc:3 mslabel:zlmediakit-mslabel
|
||||||
|
a=ssrc:3 label:zlmediakit-label-1
|
||||||
|
a=ssrc-group:FID 1 3
|
||||||
|
a=candidate:udpcandidate 1 udp 110 108.181.24.73 8000 typ host
|
||||||
|
a=candidate:tcpcandidate 1 tcp 105 108.181.24.73 8000 typ host tcptype passive
|
@ -7,52 +7,21 @@ import org.webrtc.SurfaceViewRenderer
|
|||||||
|
|
||||||
abstract class ZLMRTCPlayer {
|
abstract class ZLMRTCPlayer {
|
||||||
|
|
||||||
// companion object {
|
public abstract fun bind(surface: SurfaceViewRenderer)
|
||||||
// fun shareInstance(): ZLMRTCPlayer {
|
|
||||||
// return ZLMRTCPlayerImpl(this)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor()
|
|
||||||
|
|
||||||
public abstract fun bind(surface: SurfaceViewRenderer, localPreview:Boolean)
|
|
||||||
|
|
||||||
|
|
||||||
//拉流接口
|
//拉流接口
|
||||||
public abstract fun play(app: String, streamId: String)
|
public abstract fun play(app: String, streamId: String)
|
||||||
|
|
||||||
public abstract fun setSpeakerphoneOn(on: Boolean)
|
public abstract fun setVolume()
|
||||||
|
|
||||||
public abstract fun setLocalMute(on: Boolean)
|
|
||||||
|
|
||||||
|
|
||||||
public abstract fun stop()
|
public abstract fun stop()
|
||||||
|
|
||||||
public abstract fun pause()
|
public abstract fun pause()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public abstract fun resume()
|
public abstract fun resume()
|
||||||
|
|
||||||
public abstract fun capture(listener: (bitmap: Bitmap) -> Unit)
|
public abstract fun capture(listener: (bitmap: Bitmap) -> Unit)
|
||||||
|
|
||||||
public abstract fun record(duration: Long, result: (path: String) -> Unit)
|
public abstract fun record(duration: Long, result: (path: String) -> Unit)
|
||||||
|
|
||||||
|
|
||||||
//推流接口
|
|
||||||
// public abstract fun startLocalPreview()
|
|
||||||
//
|
|
||||||
// public abstract fun stopLocalPreview()
|
|
||||||
//
|
|
||||||
// public abstract fun startPublishing()
|
|
||||||
//
|
|
||||||
// public abstract fun stopPublishing()
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
}
|
}
|
@ -8,7 +8,12 @@ abstract class ZLMRTCPusher {
|
|||||||
|
|
||||||
public abstract fun bind(surface: SurfaceViewRenderer, localPreview: Boolean)
|
public abstract fun bind(surface: SurfaceViewRenderer, localPreview: Boolean)
|
||||||
|
|
||||||
abstract fun push(app: String, streamId: String, mode: PushMode = PushMode.CAMERA)
|
abstract fun push(
|
||||||
|
app: String,
|
||||||
|
streamId: String,
|
||||||
|
mode: PushMode = PushMode.CAMERA,
|
||||||
|
inputFile: String = ""
|
||||||
|
)
|
||||||
|
|
||||||
abstract fun stop()
|
abstract fun stop()
|
||||||
|
|
||||||
|
@ -693,8 +693,6 @@ 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.");
|
||||||
|
|
||||||
@ -720,7 +718,7 @@ public class PeerConnectionClient {
|
|||||||
rtcConfig.keyType = PeerConnection.KeyType.ECDSA;
|
rtcConfig.keyType = PeerConnection.KeyType.ECDSA;
|
||||||
// Enable DTLS for normal calls and disable for loopback calls.
|
// Enable DTLS for normal calls and disable for loopback calls.
|
||||||
rtcConfig.activeResetSrtpParams = true;//!peerConnectionParameters.loopback;
|
rtcConfig.activeResetSrtpParams = true;//!peerConnectionParameters.loopback;
|
||||||
rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN;
|
rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN; //修改模式 PlanB无法使用仅接收音视频的配置
|
||||||
|
|
||||||
PCObserver pcObserver = new PCObserver();
|
PCObserver pcObserver = new PCObserver();
|
||||||
SDPObserver sdpObserver = new SDPObserver();
|
SDPObserver sdpObserver = new SDPObserver();
|
||||||
@ -1376,7 +1374,8 @@ public class PeerConnectionClient {
|
|||||||
if (peerConnection == null || isError) {
|
if (peerConnection == null || isError) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.d(TAG, "==onAddStream tracks size:" + stream.videoTracks.size());
|
Log.d(TAG, "==onAddStream video tracks size:" + stream.videoTracks.size());
|
||||||
|
Log.d(TAG, "==onAddStream audio tracks size:" + stream.audioTracks.size());
|
||||||
if (stream.videoTracks.size() == 1) {
|
if (stream.videoTracks.size() == 1) {
|
||||||
remoteVideoTrack = stream.videoTracks.get(0);
|
remoteVideoTrack = stream.videoTracks.get(0);
|
||||||
remoteVideoTrack.setEnabled(true);
|
remoteVideoTrack.setEnabled(true);
|
||||||
@ -1386,7 +1385,6 @@ public class PeerConnectionClient {
|
|||||||
connection.videoTrack.addSink(saveVideoFileRecorder);
|
connection.videoTrack.addSink(saveVideoFileRecorder);
|
||||||
}
|
}
|
||||||
events.onRemoteRender(connection.handleId);
|
events.onRemoteRender(connection.handleId);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -16,6 +16,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.RendererCommon
|
||||||
import org.webrtc.SessionDescription
|
import org.webrtc.SessionDescription
|
||||||
import org.webrtc.StatsReport
|
import org.webrtc.StatsReport
|
||||||
import org.webrtc.SurfaceViewRenderer
|
import org.webrtc.SurfaceViewRenderer
|
||||||
@ -98,12 +99,12 @@ class ZLMRTCPlayerImpl(val context: Context) : ZLMRTCPlayer(),
|
|||||||
1280,
|
1280,
|
||||||
720,
|
720,
|
||||||
defaultFps,
|
defaultFps,
|
||||||
1024 * 1000 * 2,
|
1024 * 1024 * 2,
|
||||||
"H264",
|
"H264",
|
||||||
true,
|
true,
|
||||||
true,
|
false,
|
||||||
0,
|
0,
|
||||||
"OPUS",
|
"opus",
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
@ -116,29 +117,38 @@ class ZLMRTCPlayerImpl(val context: Context) : ZLMRTCPlayer(),
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun bind(surface: SurfaceViewRenderer, localPreview: Boolean) {
|
override fun bind(surface: SurfaceViewRenderer) {
|
||||||
this.surfaceViewRenderer = surface
|
this.surfaceViewRenderer = surface
|
||||||
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
audioManager?.isSpeakerphoneOn = false
|
audioManager?.isSpeakerphoneOn = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun play(app: String, streamId: String) {
|
override fun play(app: String, streamId: String) {
|
||||||
this.app = app
|
this.app = app
|
||||||
this.streamId = streamId
|
this.streamId = streamId
|
||||||
if (peerConnectionClient == null) peerConnectionClient = initPeerConnectionClient()
|
if (peerConnectionClient == null) peerConnectionClient = initPeerConnectionClient()
|
||||||
surfaceViewRenderer?.init(eglBase?.eglBaseContext, null)
|
surfaceViewRenderer?.init(eglBase?.eglBaseContext, object : RendererCommon.RendererEvents {
|
||||||
|
override fun onFirstFrameRendered() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFrameResolutionChanged(
|
||||||
|
videoWidth: Int,
|
||||||
|
videoHeight: Int,
|
||||||
|
rotation: Int
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
peerConnectionClient?.setAudioEnabled(true)
|
peerConnectionClient?.setAudioEnabled(true)
|
||||||
peerConnectionClient?.createPeerConnectionFactory(PeerConnectionFactory.Options())
|
peerConnectionClient?.createPeerConnectionFactory(PeerConnectionFactory.Options())
|
||||||
peerConnectionClient?.createPeerConnection(createVideoCapture(context), localHandleId)
|
peerConnectionClient?.createPeerConnection(createVideoCapture(context), localHandleId)
|
||||||
peerConnectionClient?.createOffer(localHandleId)
|
peerConnectionClient?.createOffer(localHandleId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setSpeakerphoneOn(on: Boolean) {
|
|
||||||
audioManager?.isSpeakerphoneOn = on
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setLocalMute(on: Boolean) {
|
override fun setVolume() {
|
||||||
audioManager?.isSpeakerphoneOn = on
|
audioManager?.isSpeakerphoneOn = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun stop() {
|
override fun stop() {
|
||||||
@ -167,8 +177,9 @@ class ZLMRTCPlayerImpl(val context: Context) : ZLMRTCPlayer(),
|
|||||||
|
|
||||||
override fun record(duration: Long, result: (path: String) -> Unit) {
|
override fun record(duration: Long, result: (path: String) -> Unit) {
|
||||||
|
|
||||||
val savePath = context.cacheDir.absoluteFile.absolutePath + File.separator + System.currentTimeMillis() + ".mp4"
|
val savePath =
|
||||||
peerConnectionClient?.setRecordEnable(true,savePath)
|
context.cacheDir.absoluteFile.absolutePath + File.separator + System.currentTimeMillis() + ".mp4"
|
||||||
|
peerConnectionClient?.setRecordEnable(true, savePath)
|
||||||
Handler().postDelayed({
|
Handler().postDelayed({
|
||||||
peerConnectionClient?.setRecordEnable(false, savePath)
|
peerConnectionClient?.setRecordEnable(false, savePath)
|
||||||
}, duration)
|
}, duration)
|
||||||
|
@ -18,6 +18,7 @@ import org.webrtc.Camera1Enumerator
|
|||||||
import org.webrtc.Camera2Enumerator
|
import org.webrtc.Camera2Enumerator
|
||||||
import org.webrtc.CameraEnumerator
|
import org.webrtc.CameraEnumerator
|
||||||
import org.webrtc.EglBase
|
import org.webrtc.EglBase
|
||||||
|
import org.webrtc.FileVideoCapturer
|
||||||
import org.webrtc.IceCandidate
|
import org.webrtc.IceCandidate
|
||||||
import org.webrtc.PeerConnectionFactory
|
import org.webrtc.PeerConnectionFactory
|
||||||
import org.webrtc.ScreenCapturerAndroid
|
import org.webrtc.ScreenCapturerAndroid
|
||||||
@ -36,8 +37,6 @@ class ZLMRTCPusherImpl(val context: FragmentActivity) : ZLMRTCPusher(),
|
|||||||
|
|
||||||
private var eglBase: EglBase? = null
|
private var eglBase: EglBase? = null
|
||||||
|
|
||||||
private var defaultFps = 24
|
|
||||||
|
|
||||||
private var surfaceViewRenderer: SurfaceViewRenderer? = null
|
private var surfaceViewRenderer: SurfaceViewRenderer? = null
|
||||||
|
|
||||||
private var localHandleId = BigInteger.valueOf(Random(2048).nextLong())
|
private var localHandleId = BigInteger.valueOf(Random(2048).nextLong())
|
||||||
@ -140,7 +139,7 @@ class ZLMRTCPusherImpl(val context: FragmentActivity) : ZLMRTCPusher(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun push(app: String, streamId: String, mode: PushMode) {
|
override fun push(app: String, streamId: String, mode: PushMode, inputFile: String) {
|
||||||
this.app = app
|
this.app = app
|
||||||
this.streamId = streamId
|
this.streamId = streamId
|
||||||
if (peerConnectionClient == null) peerConnectionClient = initPeerConnectionClient()
|
if (peerConnectionClient == null) peerConnectionClient = initPeerConnectionClient()
|
||||||
@ -174,10 +173,9 @@ class ZLMRTCPusherImpl(val context: FragmentActivity) : ZLMRTCPusher(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
peerConnectionClient?.createPeerConnection(FileVideoCapturer(inputFile), localHandleId)
|
||||||
|
peerConnectionClient?.createOffer(localHandleId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun stop() {
|
override fun stop() {
|
||||||
|
Loading…
Reference in New Issue
Block a user