Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6295788
redesign MediaStream and mediaStreamTrack to support multiple track.
koseyile Jul 1, 2019
f7310c6
delete member variable videoTrackToRts and AudioTracks from mediaStream.
koseyile Jul 1, 2019
b879c16
Start the name with an uppercase letter.
koseyile Jul 2, 2019
4b296dd
remove the temporary comment code.
koseyile Jul 2, 2019
e924c1d
remove unused comments.
koseyile Jul 2, 2019
2e903d0
add new method "createVideoTrack" to Context class.
koseyile Jul 9, 2019
936991a
video and audio share one mediaStream.
koseyile Jul 9, 2019
c12b797
Merge branch 'multiple_resolution' into multiple_video_capturer
koseyile Jul 9, 2019
f3972bd
change name "videostream" to "mediastream" and add audio track to me…
koseyile Jul 9, 2019
e400b81
decoupling streams and tracks. delete these functions: CaptureVideoSt…
koseyile Jul 11, 2019
7eedfb7
make DummyVideoEncoder support multiple capturer.
koseyile Jul 12, 2019
3e6aa8d
capturers share one nvEncoder.
koseyile Jul 15, 2019
c82dab4
delete parameter label from MediaStream constructor
koseyile Jul 15, 2019
cdf98ea
delete test code.
koseyile Jul 16, 2019
c88c322
changed instance type to build on Yamato
karasusan Jul 21, 2019
0a13fce
remove RTCPeerConnection when the RTCPeerConnection is disconnected.
koseyile Jul 22, 2019
52138b1
add auto testing to check multiple video tracks.
koseyile Jul 22, 2019
09ab522
rename NvVideoCapturer to UnityVideoCapturer
koseyile Jul 22, 2019
5d00ed0
add abstract bass class : UnityEncoder.
koseyile Jul 22, 2019
ed8916a
let DummyVideoEncoderFactory manage the encoder of platform.
koseyile Jul 22, 2019
ec8bbb1
each nvEncoder has a texture buffer.
koseyile Jul 22, 2019
3e248ea
delete comment code.
koseyile Jul 23, 2019
309436b
change pEncoderInterface to no-static.
koseyile Jul 23, 2019
ce51d0f
web app can switch two resolution to show.
koseyile Aug 5, 2019
f56b2ca
same resolution nvEncoders share input texture.
koseyile Aug 12, 2019
c9edf21
add other way to implement simulcast
koseyile Aug 12, 2019
9c85620
add select media stream ui.
koseyile Aug 15, 2019
dd1335e
web app can select media stream.
koseyile Aug 19, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .yamato/upm-ci-webrtc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ editors:
- version: trunk
platforms:
- name: win
type: Unity::VM
type: Unity::VM::GPU
# currently the projects depends MSBuild. we should replace CMake
# image: package-ci/win10:stable
image: renderstreaming/win10:latest
Expand Down Expand Up @@ -101,4 +101,4 @@ publish:
- .yamato/upm-ci-webrtc.yml#test_{{ platform.name }}_{{ editor.version }}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
92 changes: 80 additions & 12 deletions Assets/Scripts/RenderStreaming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public class ButtonClickElement
public ButtonClickEvent click;
}

public class CameraMediaStream
{
public Camera camera;
public MediaStream[] mediaStreams = new MediaStream[2];
}

public class RenderStreaming : MonoBehaviour
{
#pragma warning disable 0649
Expand All @@ -29,19 +35,19 @@ public class RenderStreaming : MonoBehaviour
[SerializeField, Tooltip("Time interval for polling from signaling server")]
private float interval = 5.0f;

[SerializeField, Tooltip("Camera to capture video stream")]
private Camera captureCamera;

[SerializeField]
private ButtonClickElement[] arrayButtonClickEvent;

[SerializeField]
private bool isUseMinimalTextures = true;
#pragma warning restore 0649

private Signaling signaling;
private Dictionary<string, RTCPeerConnection> pcs = new Dictionary<string, RTCPeerConnection>();
private Dictionary<RTCPeerConnection, Dictionary<int, RTCDataChannel>> mapChannels = new Dictionary<RTCPeerConnection, Dictionary<int, RTCDataChannel>>();
private RTCConfiguration conf;
private string sessionId;
private MediaStream videoStream;
private Dictionary<Camera, CameraMediaStream> cameraMediaStreamDict = new Dictionary<Camera, CameraMediaStream>();

public void Awake()
{
Expand All @@ -52,6 +58,7 @@ public void Awake()

public void OnDestroy()
{
Audio.Stop();
WebRTC.WebRTC.Finalize();
}
public IEnumerator Start()
Expand All @@ -60,7 +67,47 @@ public IEnumerator Start()
{
yield break;
}
videoStream = captureCamera.CaptureStream(1280, 720);


if (isUseMinimalTextures)
{
foreach (var camera in Camera.allCameras)
{
CameraMediaStream cameraMediaStream = new CameraMediaStream();
cameraMediaStreamDict.Add(camera, cameraMediaStream);
camera.CreateRenderStreamTexture(1280, 720);
int mediaCount = cameraMediaStream.mediaStreams.Length;
for (int i = 0; i < mediaCount; ++i)
{
cameraMediaStream.mediaStreams[i] = new MediaStream();
RenderTexture rt = camera.GetStreamTexture(0);
int temp = i==0 ? 1 : (int)Mathf.Pow(i + 1, 10);
VideoStreamTrack videoTrack = new VideoStreamTrack("videoTrack" + i, rt, 1000000/temp);
cameraMediaStream.mediaStreams[i].AddTrack(videoTrack);
cameraMediaStream.mediaStreams[i].AddTrack(new AudioStreamTrack("audioTrack"));
}
}
}else{
foreach (var camera in Camera.allCameras)
{
CameraMediaStream cameraMediaStream = new CameraMediaStream();
cameraMediaStreamDict.Add(camera, cameraMediaStream);
camera.CreateRenderStreamTexture(1280, 720, cameraMediaStream.mediaStreams.Length);
int texCount = camera.GetStreamTextureCount();
for (int i = 0; i < texCount; ++i)
{
int index = i;
cameraMediaStream.mediaStreams[i] = new MediaStream();
RenderTexture rt = camera.GetStreamTexture(index);
VideoStreamTrack videoTrack = new VideoStreamTrack("videoTrack" + i, rt);
cameraMediaStream.mediaStreams[i].AddTrack(videoTrack);
cameraMediaStream.mediaStreams[i].AddTrack(new AudioStreamTrack("audioTrack"));
}
}
}

Audio.Start();

signaling = new Signaling(urlSignaling);
var opCreate = signaling.Create();
yield return opCreate;
Expand Down Expand Up @@ -125,27 +172,45 @@ IEnumerator GetOffer()
{
continue;
}
var pc = new RTCPeerConnection();
pcs.Add(offer.connectionId, pc);

RTCConfiguration config = default;
config.iceServers = new RTCIceServer[]
{
new RTCIceServer { urls = urlsIceServer },
};
config.bundle_policy = RTCBundlePolicy.kBundlePolicyMaxBundle;
var pc = new RTCPeerConnection(ref config);
pcs.Add(offer.connectionId, pc);
pc.OnDataChannel = new DelegateOnDataChannel(channel => { OnDataChannel(pc, channel); });
pc.SetConfiguration(ref conf);
pc.OnIceCandidate = new DelegateOnIceCandidate(candidate => { StartCoroutine(OnIceCandidate(offer.connectionId, candidate)); });
pc.OnIceConnectionChange = new DelegateOnIceConnectionChange(state =>
{
if(state == RTCIceConnectionState.Disconnected)
{
pc.Close();
pc.Close();
pcs.Remove(offer.connectionId);
}
});

//make video bit rate starts at 16000kbits, and 160000kbits at max.
string pattern = @"(a=fmtp:\d+ .*level-asymmetry-allowed=.*)\r\n";
_desc.sdp = Regex.Replace(_desc.sdp, pattern, "$1;x-google-start-bitrate=16000;x-google-max-bitrate=160000\r\n");
Debug.Log("remote sdp---------------------------------------------------------");
Debug.Log(_desc.sdp);

pc.SetRemoteDescription(ref _desc);
foreach (var track in videoStream.GetTracks())

foreach (var k in cameraMediaStreamDict.Keys)
{
pc.AddTrack(track);
foreach (var mediaStream in cameraMediaStreamDict[k].mediaStreams)
{
foreach (var track in mediaStream.GetTracks())
{
pc.AddTrack(track, mediaStream.Id);
}
}
}

StartCoroutine(Answer(connectionId));
}
}
Expand All @@ -163,12 +228,14 @@ IEnumerator Answer(string connectionId)
}
var opLocalDesc = pc.SetLocalDescription(ref op.desc);
yield return opLocalDesc;
Debug.Log("local sdp---------------------------------------------------------");
Debug.Log(op.desc.sdp);
if (opLocalDesc.isError)
{
Debug.LogError($"Network Error: {opLocalDesc.error}");
yield break;
}
var op3 = signaling.PostAnswer(this.sessionId, connectionId, op.desc.sdp);
var op3 = signaling.PostAnswer(this.sessionId, connectionId, op.desc.sdp);
yield return op3;
if (op3.webRequest.isNetworkError)
{
Expand Down Expand Up @@ -202,6 +269,7 @@ IEnumerator GetCandidate()
{
continue;
}

foreach (var candidate in candidateContainer.candidates)
{
RTCIceCandidate _candidate = default;
Expand Down
Loading