Google VR SDK (Unity) - GvrVideoPlayerTexture swap URL - c#

I'm working with the Google VR SDK for Unity trying to build a simple 360 Video viewer using the components that come with the SDK. I'm trying to extend their PanoVideoSample to dynamically change the source video when the user navigates from a menu.
I'm having trouble changing the URL for the GvrVideoPlayerTexture via code. In their demo scene (VideoDemo) they have a PanoVideoSample that contains a Video Sphere, which you can edit the GVRVideoPlayerTexture script in the inspector panel to point at the proper video URL.
I'd like to dynamically set the video URL in C# rather than hard-code a bunch of individual video spheres then hide/show them. I've almost got this working with the following code.
public void SwapVideo(int index){
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().videoURL = urls [index];// my new url
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture>().ReInitializeVideo ();
videoSphere.SetActive (true);
}
public void ReturnToMainMenu(){
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture>().CleanupVideo();
videoSphere.SetActive (false);
this.gameObject.SetActive (true);
}
The code above seems to work, but the problem is the texture on the videoSphere turns white after the url is set and the texture is re-initialized. I can see that the new video loads and I can hear the audio for the new video, but the scene just shows a white texture.
See the output here
I'm wondering if I'm missing a key step on the GvrVideoPlayerTexture or perhaps additional calls to update the StereoPanoSphereMaterial that is used to render the scene. This SDK is pretty new and there doesn't seem to be many people writing about it, so any help is appreciated.

I eventually found the answer to my question in the documentation on the Google VR docs (Streaming Video Support).
I'm still not totally clear what I was doing wrong in my first attempt, but this is the code that worked for me.
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().videoURL = urls [index];
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().videoType = GvrVideoPlayerTexture.VideoType.Other;
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().videoProviderId = string.Empty;
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().videoContentID = string.Empty;
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().CleanupVideo ();
videoSphere.GetComponentInChildren<GvrVideoPlayerTexture> ().ReInitializeVideo ();

Related

Unity VideoPlayer lags when playing local file using a url

I am playing a 360 3D video using a skybox.
At first I had the video as an asset and it worked fine, without any lag.
The problem is the video is 7GB and it is not suitable to have it as an asset but it is preferable to store it on the Headset (PICO) and then read it using the url parameter of the VideoPlayer component :
videoPlayer5 = GetComponent<VideoPlayer>().gameObject.AddComponent<UnityEngine.Video.VideoPlayer>();
videoPlayer5.url = #"/storage/self/primary/Android/obb/com.Com.MyCompany.Namespace.Appname\VideoFile.mp4";
videoPlayer5.renderMode = UnityEngine.Video.VideoRenderMode.RenderTexture;
videoPlayer5.targetTexture = VideoTexture;
videoPlayer5.SetDirectAudioMute(0, true);
But by doing so, the video does not play smoothly, it "lags".
Is there any particular reason for this ? Can anything be done to fix that ?
Thank
The problem was indeed the video encoding. Optimizing the video fixed the problem.

I can't play UDP video stream whit LibVLCSharp

I am beginning to learn how to use the LibVLCSharp library. Right now I am trying to play a streaming video that comes to me in multicast UDP, 224.XX.XX.XX:PORT. The problem is that said video comes to me without format.
I get to reproduce it in cmd with:
vlc udp://#224.XX.XX.XX:PORT --demux=mp4v --rawvid-fps=12
This is mi code:
public void PlayURLFile(string file)
{
var media = new Media(_libVLC, "udp://#224.XX.XX.XX:XXXXX");
media.AddOption(":demux=mp4v");
media.AddOption(":rawvid-fps=12");
_mp.Play(media);
isPlaying = true;
}
When executing it does not show me any error.
The videoview I have to show the video shows me the black screen.
I understand that the problem may be that I am not entering AddOption correctly or that the options are different. But after fighting with the code and looking at documentation, I can't find an answer that is clarifying.
Can someone help me?
Greetings and thank you.
Give the following options in the LibVLC ctor instead.
new LibVLC("--demux=mp4v", "--rawvid-fps=12");

Change Image Texture Type to "Cubemap" using Unity Scripting API

Using Unity Inspector, it is easy to change Texture Type of image to Cubemap (Image Attached Below)
I want to achieve the same using C# script. Googled a lot to find nothing specific.
First, I make a network call to download my panaromic 360 image and wait for it to yield. All good!
image = new WWW (subplacesList [this.curSubPlace].getImage ());
while( !image.isDone ) {
curLoading = image.progress * 100;
progressImg.fillAmount = image.progress;
yield return null;
}
The above code gives me WWW object. I can convert to Texture2D Object using image.texture but that is not what I want.
I'm trying to change the image type to Cubemap so that I can apply it to a material and change the skybox.
Note: I have been downloading the image and wrapping it to a Unlit/InsideVisible sphere as an alternative but it's pretty crappy. Any help would be appreciated!

Unity3d - 2 issues with Facebook Sharing in Window Phone

Everybody,I must say that I have post this question 3 times in Unity Community (include answer hub and its forum) but no one can solve it.
I use TakeScreenShot() function (it's in the InteractiveConsole example in FB SDK for Unity) to take a screenshot and post it to FB. But there are 2 problems appeared:
First: the screenshot that's captured is a gray blank like this: http://i7.minus.com/iXiHlCcSWaVfC.jpg
Second: No one can see my post except me although I set the photo to public.
How can I fix these problems?
Here is the code of TakeScreenShot() function:
private IEnumerator TakeScreenshot() {
yield return new WaitForEndOfFrame();
var width = Screen.width;
var height = Screen.height;
var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
byte[] screenshot = tex.EncodeToPNG();
var wwwForm = new WWWForm();
wwwForm.AddBinaryData("image", screenshot, "InteractiveConsole.png");
wwwForm.AddField("message", "herp derp. I did a thing! Did I do this right?");
FB.API("me/photos", Facebook.HttpMethod.POST, Callback, wwwForm);
Debug.Log("done");
}
I hope you solved your issues but I will answer anyways to your questions:
•First: the screenshot that's captured is a gray blank.
I think this works for Windows Phone only since very recently on Unity 4.5, update and try again.
Unity 4.5 Windows Phone Fixes
Grey Textures happen if you forget to call the Apply method. You will end up with a grey texture if forget to call. I see you are calling tex.Apply() but my guess is that you added it later and you may be seeing an old grey texture. Your code should work as it is. If you still get the grey Texture after updating to version 4.5 or later, try to wait a little time between the Apply and calling the EncodeToPNG(), maybe yield between those calls. Bear in mind that both are expensive operations.
•Second: No one can see my post except me although I set the photo to public.
That is because you have not go live (public) with you facebook app, during development only you will see you and your development team will see the messages. By the way fecebook will not approve hardcoded messages so even though this may work, and I know you based your code on facebook own smaples, you will need to allow the user to edit the message before posting.

Getting MP4 File Duration with DirectShow

I need to get the duration of an mp4 file, preferably as a double in seconds. I was using DirectShow (see code below), but it keeps throwing a particularly unhelpful error. I'm wondering if someone has an easy solution to this. (Seriously, who knew that getting that information would be so difficult)
public static void getDuration(string moviePath)
{
FilgraphManager m_objFilterGraph = null;
m_objFilterGraph = new FilgraphManager();
m_objFilterGraph.RenderFile(moviePath);
IMediaPosition m_objMediaPosition = null;
m_objMediaPosition = m_objFilterGraph as IMediaPosition;
Console.WriteLine(m_objMediaPosition.Duration);
}
Whenever I run this code, I get the error: "Exception from HRESULT: 0x80040265"
I also tried using this: Getting length of video
but it doesn't work either because I don't think that it works on MP4 files.
Seriously, I feel like there has to be a much easier way to do this.
Note: I would prefer to avoid using exe's like ffmpeg and then parsing the output to get the information.
You are approaching the problem correctly. You need to build a good pipeline starting from source .MP4 file and up to video and audio renderers. Then IMediaPosition.Duration will get you what you want. Currently you are getting VFW_E_UNSUPPORTED_STREAM because you cannot build the pipeline.
Note that there is no good support for MPEG-4 in DirectShow in clean Windows, you need a third party parser installed to add missing blocks. This is the likely cause of your problem. There are good Free DirectShow Mpeg-4 Filters available to fill this gap.
The code sample under the link Getting length of video is basically valid too, however it uses deprecated component which in additional make additional assumptions onto the media file in question. Provided that there is support for .MP4 in the system, IMediaPosition.Duration is to give you what you look for.
You can use get_Duration() from IMediaPosition interface.
This return a double value with the video duration in seconds.
Double Lenght;
m_FilterGraph = new FilterGraph()
//Configure the FilterGraph()
m_mediaPosition = m_FilterGraph as IMediaPosition;
m_mediaPosition.get_Duration(out Length);
Using Windows Media Player Component also, we can get the duration of the video.
I hope that following code snippet may help you guys :
using WMPLib;
// ...
var player = new WindowsMediaPlayer();
var clip = player.newMedia(filePath);
Console.WriteLine(TimeSpan.FromSeconds(clip.duration));
and don't forget to add the reference of wmp.dll which will be
present in System32 folder.

Categories

Resources