Video plays before Vuforia image target recognition

I noticed that a video placed on a quad that is a child of a Vuforia image target starts playing immediately. I found a very detailed tutorial that addresses this specific issue by editing the DefaultTrackableEventHandler script. Unfortunately, the changes to the script generate errors in my development setting. The tutorial was done with Unity3D 2017.3 and Vuforia 7. I am using 2018.3.0f2 personal version and Vuforia 7.5.26. This issue was addressed at time 32:05 in the following video: https://youtu.be/4W5e6-TSpW0
I have done my due diligence looking at the core samples including the fissure image target in the 3-ImageTargets scene. I have Googled the topic to death, and canā€™t get it working. I am including the script from the YouTube tutorial in case someone with experience can spot what needs to be changed. I would be incredibly grateful for the help!

/*==============================================================================
Copyright (c) 2017 PTC Inc. All Rights Reserved.

Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Protected under copyright and other laws.
==============================================================================*/

using UnityEngine;
using Vuforia;

// need to import video functionality
using UnityEngine.Video;
[RequireComponent(typeof(VideoPlayer))]

/// <summary>
///     A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour, ITrackableEventHandler
{
    #region PRIVATE_MEMBER_VARIABLES

    protected TrackableBehaviour mTrackableBehaviour;
// setup the videoPlayer object
private VideoPlayer videoPlayer;

    #endregion // PRIVATE_MEMBER_VARIABLES

    #region UNTIY_MONOBEHAVIOUR_METHODS

    protected virtual void Start()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
        if (mTrackableBehaviour)
            mTrackableBehaviour.RegisterTrackableEventHandler(this);

  // add the following 4 lines to get the reference to the video player component of the plane that the video is attached to
  // IMPORTANT: set "Video_plane" to the name of the plane game object you attached your video to
  GameObject video = GameObject.Find ("Video_plane");
  videoPlayer = video.GetComponent<VideoPlayer>();
  videoPlayer.Play();
  videoPlayer.Pause();
  // see the VideoPlayer Scripting API for more ideas on which functions you can use in your code
  // for example changing the playback speed or jumping to a speicific point in time:
  // https://docs.unity3d.com/ScriptReference/Video.VideoPlayer.html

    }

    #endregion // UNTIY_MONOBEHAVIOUR_METHODS

    #region PUBLIC_METHODS

    /// <summary>
    ///     Implementation of the ITrackableEventHandler function called when the
    ///     tracking state changes.
    /// </summary>
    public void OnTrackableStateChanged(
        TrackableBehaviour.Status previousStatus,
        TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED ||
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
   //Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
   // Play the video:
   Debug.Log("Play!");
   OnTrackingFound();
   videoPlayer.Play();
  }
  else if (previousStatus == TrackableBehaviour.Status.TRACKED &&
   newStatus == TrackableBehaviour.Status.NOT_FOUND)
  {
   //Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
   // Pause the video, if using Stop() the video would always play back from the beginning again
   Debug.Log("Stop!");
   OnTrackingLost();
   videoPlayer.Pause();
        }
        else
        {
            // For combo of previousStatus=UNKNOWN + newStatus=UNKNOWN|NOT_FOUND
            // Vuforia is starting, but tracking has not been lost or found yet
            // Call OnTrackingLost() to hide the augmentations
            OnTrackingLost();
        }
    }

    #endregion // PUBLIC_METHODS

    #region PRIVATE_METHODS

    protected virtual void OnTrackingFound()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);

        // Enable rendering:
        foreach (var component in rendererComponents)
            component.enabled = true;

        // Enable colliders:
        foreach (var component in colliderComponents)
            component.enabled = true;

        // Enable canvas':
        foreach (var component in canvasComponents)
            component.enabled = true;
    }


    protected virtual void OnTrackingLost()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);

        // Disable rendering:
        foreach (var component in rendererComponents)
            component.enabled = false;

        // Disable colliders:
        foreach (var component in colliderComponents)
            component.enabled = false;

        // Disable canvas':
        foreach (var component in canvasComponents)
            component.enabled = false;
    }

    #endregion // PRIVATE_METHODS
1 Like

Iā€™ve got the exact same issue. So if anybody knows the answer to this, please share.

Unfortunately, the changes to the script generate errors in my development setting.

Thats not specific enough. What are the errors, what are you expecting to happen that isnā€™t happening or vice versa.

As far as the script is concerned, the only error it gave me was ā€œAssets/VideoPlay.cs(72,49): error CS0117: ā€˜TrackableBehaviour.Statusā€™ does not contain a definition for ā€˜NOT_FOUNDā€™ā€. Iā€™ve fixed the error, but unfortunately the script is not solving the original problem. When the app is started, the videoā€™s (before they are detected) start playing. The audio, however, only starts playing when a target is detected. Therefore, the audio and video donā€™t align.

(Iā€™ve created a short video in which I demonstrate the issue, you can find it here: Arvideotest.mp4 - Google Drive . sorry for the crappy quality, my computer wonā€™t record the screen.)

My question would be: Is there a function to stop (not pause) the video when target is lost? Iā€™m using this piece of code for the audio:

     void StopAllAudio()
        {
            allAudioSources = FindObjectsOfType(typeof(AudioSource)) as AudioSource[];
            foreach (AudioSource audioS in allAudioSources)
            {
                audioS.Stop();
            }
        }

Why would you want to stop / start the audiosource separately? The videoplayer should do so automatically, assuming youā€™re playing the audio embedded in the video file and not a separate audio file.

Could you post your entire trackable eventhandler script? I downloaded the adapted script from the youtube tutorial and it doesnā€™t mention audiosources.

Iā€™m playing the audio as a separate audio file, because when I had the audio embedded in the video file, it did not mute/pause/stop the audio when the target was lost. This resulted in the audio looping indefinitely without a target being present (I made a video in which I demonstrate this issue: AR_test_Diggit Magazine.mp4 - Google Drive)

Hereā€™s my current code:

/*==============================================================================
Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Protected under copyright and other laws.
==============================================================================*/

using UnityEngine;

//Add This script
using System.Collections;
using System.Collections.Generic;


namespace Vuforia
{
    /// <summary>
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// </summary>
    public class DefaultTrackableEventHandler : MonoBehaviour,
                                                ITrackableEventHandler
    {

        //------------Begin Sound----------
        public AudioSource soundTarget;
        public AudioClip clipTarget;
        private AudioSource[] allAudioSources;

        //function to stop all sounds
        void StopAllAudio()
        {
            allAudioSources = FindObjectsOfType(typeof(AudioSource)) as AudioSource[];
            foreach (AudioSource audioS in allAudioSources)
            {
                audioS.Stop();
            }
        }

        //function to play sound
        void playSound(string ss)
        {
            clipTarget = (AudioClip)Resources.Load(ss);
            soundTarget.clip = clipTarget;
            soundTarget.loop = false;
            soundTarget.playOnAwake = false;
            soundTarget.Play();
        }

        //-----------End Sound------------


        #region PRIVATE_MEMBER_VARIABLES

        private TrackableBehaviour mTrackableBehaviour;

        #endregion // PRIVATE_MEMBER_VARIABLES



        #region UNTIY_MONOBEHAVIOUR_METHODS

        void Start()
        {
            mTrackableBehaviour = GetComponent<TrackableBehaviour>();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this);
            }

            //Register / add the AudioSource as object
            soundTarget = (AudioSource)gameObject.AddComponent<AudioSource>();
        }

        #endregion // UNTIY_MONOBEHAVIOUR_METHODS



        #region PUBLIC_METHODS

        /// <summary>
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        /// </summary>
        public void OnTrackableStateChanged(
                                        TrackableBehaviour.Status previousStatus,
                                        TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                OnTrackingFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS



        #region PRIVATE_METHODS


        private void OnTrackingFound()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }

            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");


            //Play Sound, IF detect an target

            if (mTrackableBehaviour.TrackableName == "AR_Jan-1")
            {
                playSound("audio/AR_Jan 1_audio");
            }

            if (mTrackableBehaviour.TrackableName == "AR_Odile-1")
            {
                playSound("audio/AR_Odile 1_audio");
            }

        }


        private void OnTrackingLost()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Disable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = false;
            }

            // Disable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = false;
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");

            //Stop All Sounds if Target Lost
            StopAllAudio();
        }



        #endregion // PRIVATE_METHODS
    }
}

Iā€™m happy with the way itā€™s handling the audio at this moment. If the video-part could do the exact same thing as the audio-part, Iā€™d be very happy. Hope youā€™re able to help.

Can you tell me how you solved this? ā€œAssets/VideoPlay.cs(72,49): error CS0117: ā€˜TrackableBehaviour.Statusā€™ does not contain a definition for ā€˜NOT_FOUNDā€™ā€

Iā€™m having this same issue and canā€™t find any current code that can fix the issue. Any luck yet?

I am having similar issues.
An Ar camera
ImageTarget with QUAD as child with the video player component.

I have tried with embedded audio, a separate audio source
Play on Awake On and off.

But its never correct.
The audio either starts immediately before the tracked image is found, and just carries on. The video does not pause when it stops tracking.
Any help would b appreciated.
jm

1 Like

instead of NOT FOUND write: Limited

TrackableBehaviour.Status.NOT_FOUND)

it was changed in unity 2019 by

TrackableBehaviour.Status.NO_POSE)

1 Like

I did refer the table in this link: https://library.vuforia.com/content/vuforia-library/en/reference/unity/classVuforia_1_1TrackableBehaviour.html#a67a0db04d321a74b7e7fcfd3f1a3f70baf8c96098a30de26eecad683692f70169

Replaced, TrackableBehaviour.Status.NOT_FOUND with TrackableBehaviour.Status.NO_POSE and it worked.

So Iā€™m using Unity 2020.3 I had the same issue, I was able to fix it by going to the ā€œimage targetā€ ā†’ ā€œVideo Trackable Event Handlerā€ and changing the ā€œStatus Filterā€ from ā€œTracked_Extended Trackedā€ to ā€œTrackedā€

Also thank you for the link to the Lecture, I needed to use the scripts he provided to get it to work