Skip to content

Instantly share code, notes, and snippets.

@jakep84 jakep84/ScreenShare.cs Secret

Last active Jun 20, 2020
Embed
What would you like to do?
How to screenshare with Agora.io and unity3d
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using agora_gaming_rtc;
using UnityEngine.UI;
using System.Globalization;
using System.Runtime.InteropServices;
using System;
public class ShareScreen : MonoBehaviour
{
Texture2D mTexture;
Rect mRect;
[SerializeField]
private string appId = "Your_AppID";
[SerializeField]
private string channelName = "agora";
public IRtcEngine mRtcEngine;
int i = 100;
void Start()
{
Debug.Log("ScreenShare Activated");
mRtcEngine = IRtcEngine.getEngine(appId);
// enable log
mRtcEngine.SetLogFilter(LOG_FILTER.DEBUG | LOG_FILTER.INFO | LOG_FILTER.WARNING | LOG_FILTER.ERROR | LOG_FILTER.CRITICAL);
// set callbacks (optional)
mRtcEngine.SetParameters("{\"rtc.log_filter\": 65535}");
//Configure the external video source
mRtcEngine.SetExternalVideoSource(true, false);
// Start video mode
mRtcEngine.EnableVideo();
// allow camera output callback
mRtcEngine.EnableVideoObserver();
// join channel
mRtcEngine.JoinChannel(channelName, null, 0);
//Create a rectangle width and height of the screen
mRect = new Rect(0, 0, Screen.width, Screen.height);
//Create a texture the size of the rectangle you just created
mTexture = new Texture2D((int)mRect.width, (int)mRect.height, TextureFormat.BGRA32, false);
}
void Update()
{
//Start the screenshare Coroutine
StartCoroutine(shareScreen());
}
//Screen Share
IEnumerator shareScreen()
{
yield return new WaitForEndOfFrame();
//Read the Pixels inside the Rectangle
mTexture.ReadPixels(mRect, 0, 0);
//Apply the Pixels read from the rectangle to the texture
mTexture.Apply();
// Get the Raw Texture data from the the from the texture and apply it to an array of bytes
byte[] bytes = mTexture.GetRawTextureData();
// Make enough space for the bytes array
int size = Marshal.SizeOf(bytes[0]) * bytes.Length;
// Check to see if there is an engine instance already created
IRtcEngine rtc = IRtcEngine.QueryEngine();
//if the engine is present
if (rtc != null)
{
//Create a new external video frame
ExternalVideoFrame externalVideoFrame = new ExternalVideoFrame();
//Set the buffer type of the video frame
externalVideoFrame.type = ExternalVideoFrame.VIDEO_BUFFER_TYPE.VIDEO_BUFFER_RAW_DATA;
// Set the video pixel format
externalVideoFrame.format = ExternalVideoFrame.VIDEO_PIXEL_FORMAT.VIDEO_PIXEL_BGRA;
//apply raw data you are pulling from the rectangle you created earlier to the video frame
externalVideoFrame.buffer = bytes;
//Set the width of the video frame (in pixels)
externalVideoFrame.stride = (int)mRect.width;
//Set the height of the video frame
externalVideoFrame.height = (int)mRect.height;
//Remove pixels from the sides of the frame
externalVideoFrame.cropLeft = 10;
externalVideoFrame.cropTop = 10;
externalVideoFrame.cropRight = 10;
externalVideoFrame.cropBottom = 10;
//Rotate the video frame (0, 90, 180, or 270)
externalVideoFrame.rotation = 180;
// increment i with the video timestamp
externalVideoFrame.timestamp = i++;
//Push the external video frame with the frame we just created
int a = rtc.PushVideoFrame(externalVideoFrame);
Debug.Log(" pushVideoFrame = " + a);
}
}
}
@gtk2k

This comment has been minimized.

Copy link

gtk2k commented Jan 21, 2020

I have error
“‘IRtcEngine’ does not contain a definition for ‘PushExternVideoFrame’ and no accessible extension method ‘PushExternVideoFrame’ accepting a first argument of type ‘IRtcEngine’ could be found”

@tywiggs

This comment has been minimized.

Copy link

tywiggs commented Feb 4, 2020

I think it is just "PushVideoFrame" now not sure though

@jakep84

This comment has been minimized.

Copy link
Owner Author

jakep84 commented Mar 27, 2020

Yes, just PushVideoFrame

@harsh-priyadarshi

This comment has been minimized.

Copy link

harsh-priyadarshi commented Apr 15, 2020

Hey, the code doesn't work in build. Also, because in your code you are not initializing any VideoSurface, I tried initializing it inside JoinSuccess callback. I am able to see local stream in the editor, nothing happens in build. Also, no errors popup. I have enabled all kind of logs.

@jakep84

This comment has been minimized.

Copy link
Owner Author

jakep84 commented Apr 16, 2020

Hey, the code doesn't work in build. Also, because in your code you are not initializing any VideoSurface, I tried initializing it inside JoinSuccess callback. I am able to see local stream in the editor, nothing happens in build. Also, no errors popup. I have enabled all kind of logs.

This code does not call a video surface, it shares what the users sees in the game view over a stream. Have you read the corresponding tutorial? https://medium.com/@jake_agora.io/how-to-broadcast-your-screen-with-unity3d-and-agora-io-10006b8a4aa7

@hskim-inventis

This comment has been minimized.

Copy link

hskim-inventis commented Apr 17, 2020

주석 2020-04-17 173557
Hi. I share the screen windows build unity and see the rotated image on web demo.
Why the image is rotated. Changing the rotation to 0. but the result image is rotated.
externalVideoFrame.rotation = 0;
https://webdemo.agora.io/agora-web-showcase/examples/Agora-Screen-Sharing-Web/?_ga=2.201467473.1125400638.1587082579-1090229122.1587082579

@lgotkowski

This comment has been minimized.

Copy link

lgotkowski commented May 20, 2020

I have the same rotation issue. Did you come up with a solution for it?

@ooohlee

This comment has been minimized.

Copy link

ooohlee commented May 22, 2020

same rotation issue!

@shinsim

This comment has been minimized.

Copy link

shinsim commented Jun 9, 2020

I'm using this script and the receiver have the video flipped and color issue. any solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.