예제 #1
0
        public static VideoHandle Create(string uri, Action loaded, Action <string> error)
        {
            var handle = new VideoHandle();
            var url    = new NSUrl(uri);

            handle.Asset = new AVUrlAsset(url, (AVUrlAssetOptions)null);
            handle.Asset.LoadValuesAsynchronously(new string[] { "tracks" },
                                                  () => DispatchQueue.MainQueue.DispatchAsync(
                                                      () => {
                NSError e;
                var status = handle.Asset.StatusOfValue("tracks", out e);
                if (status == AVKeyValueStatus.Loaded)
                {
                    handle.Output = new AVPlayerItemVideoOutput(
                        new CVPixelBufferAttributes
                    {
                        PixelFormatType = CVPixelFormatType.CV32BGRA,
                    });

                    handle.PlayerItem = AVPlayerItem.FromAsset(handle.Asset);
                    handle.PlayerItem.AddOutput(handle.Output);
                    handle.Player = AVPlayer.FromPlayerItem(handle.PlayerItem);
                    PollReadyState(handle, loaded, error);
                }
                else
                {
                    error("Failed to load: " + status.ToString());
                }
            }));

            return(handle);
        }
예제 #2
0
        public static void Dispose(VideoHandle handle)
        {
            if (handle.AudioPlayer != null)
            {
                handle.AudioPlayer.Dispose();
            }

            if (handle.Player != null)
            {
                handle.Player.Dispose();
            }

            if (handle.PlayerItem != null)
            {
                handle.PlayerItem.Dispose();
            }

            if (handle.Output != null)
            {
                handle.Output.Dispose();
            }

            if (handle.Asset != null)
            {
                handle.Asset.Dispose();
            }
        }
예제 #3
0
        /*public void UpdateTexture(int textureName)
         * {
         *      GL.BindTexture(TextureTarget.Texture2D, textureName);
         *      PixelBufferImpl.CVPixelBufferLockBaseAddress(_handle, CVPixelBufferLockFlags.kCVPixelBufferLock_ReadOnly);
         *      GL.TexImage2D(
         *              TextureTarget.Texture2D,
         *              0,
         *              PixelInternalFormat.Rgba,
         *              Width,
         *              Height,
         *              0,
         *              PixelFormat.Bgra,
         *              PixelType.UnsignedByte,
         *              PixelBufferImpl.CVPixelBufferGetBaseAddress(_handle));
         *      PixelBufferImpl.CVPixelBufferUnlockBaseAddress(_handle, CVPixelBufferLockFlags.kCVPixelBufferLock_ReadOnly);
         * }*/

        public void UpdateTexture(int textureName, VideoHandle handle)
        {
            var width             = Width;
            var height            = Height;
            var bytesPerRow       = BytesPerRow;
            var actualBytesPerRow = width * 4;

            PixelBufferImpl.CVPixelBufferLockBaseAddress(_handle, CVPixelBufferLockFlags.kCVPixelBufferLock_ReadOnly);

            var baseAddress   = PixelBufferImpl.CVPixelBufferGetBaseAddress(_handle);
            var sourceAddress = baseAddress;
            var sourceOffset  = 0;
            var destOffset    = 0;

            for (int y = 0; y < height; y++)
            {
                sourceOffset  = y * bytesPerRow;
                destOffset    = y * actualBytesPerRow;
                sourceAddress = new IntPtr(baseAddress.ToInt64() + (Int64)sourceOffset);
                Marshal.Copy(sourceAddress, handle.Pixels, destOffset, actualBytesPerRow);
            }

            PixelBufferImpl.CVPixelBufferUnlockBaseAddress(_handle, CVPixelBufferLockFlags.kCVPixelBufferLock_ReadOnly);

            var pinnedArray = GCHandle.Alloc(handle.Pixels, GCHandleType.Pinned);

            GL.BindTexture(TextureTarget.Texture2D, textureName);
            if (width != handle.WidthCache || height != handle.HeightCache)
            {
                handle.WidthCache  = width;
                handle.HeightCache = height;
                GL.TexImage2D(
                    TextureTarget.Texture2D,
                    0,
                    PixelInternalFormat.Rgba,
                    width,
                    height,
                    0,
                    PixelFormat.Bgra,
                    PixelType.UnsignedByte,
                    pinnedArray.AddrOfPinnedObject());
            }
            else
            {
                GL.TexSubImage2D(
                    TextureTarget.Texture2D,
                    0,
                    0,
                    0,
                    width,
                    height,
                    PixelFormat.Bgra,
                    PixelType.UnsignedByte,
                    pinnedArray.AddrOfPinnedObject());
            }

            pinnedArray.Free();
        }
예제 #4
0
        public static void UpdateTexture(VideoHandle handle, System.Int32 textureHandle)
        {
            var pixelBufferSize = GetWidth(handle) * GetHeight(handle) * 4;

            if (handle.Pixels == null || handle.Pixels.Length != pixelBufferSize)
            {
                handle.Pixels = new byte[pixelBufferSize];
            }

            var rt = new CMTime();

            using (var buffer = CopyPixelBuffer(handle.Output, handle.PlayerItem.CurrentTime, ref rt))
                buffer.UpdateTexture(textureHandle, handle);
        }
예제 #5
0
        public static int GetRotation(VideoHandle handle)
        {
            var degrees = 0;
            var tracks  = handle.Asset.Tracks;

            foreach (var track in tracks)
            {
                if (track.MediaType.Equals(AVMediaType.Video))
                {
                    var transform = track.PreferredTransform;
                    var angle     = Math.Atan2(transform.yx, transform.xx);
                    degrees = (int)(angle * (180.0 / Math.PI));
                    break;
                }
            }
            return(degrees);
        }
예제 #6
0
        static void PollReadyState(VideoHandle handle, Action ready, Action <string> error)
        {
            switch (handle.PlayerItem.Status)
            {
            case AVPlayerItemStatus.ReadyToPlay:
                ready();
                break;

            case AVPlayerItemStatus.Failed:
                error("Failed to load: " + handle.PlayerItem.Status.ToString());
                break;

            default:
                DispatchQueue.MainQueue.DispatchAsync(() => PollReadyState(handle, ready, error));
                break;
            }
        }
예제 #7
0
 public static void Stop(VideoHandle handle)
 {
     Pause(handle);
     SetPosition(handle, 0.0);
 }
예제 #8
0
 public static void SetVolume(VideoHandle handle, float volume)
 {
     handle.Player.Volume = volume;
 }
예제 #9
0
 public static float GetVolume(VideoHandle handle)
 {
     return(handle.Player.Volume);
 }
예제 #10
0
 public static int GetHeight(VideoHandle handle)
 {
     return(handle.PlayerItem.PresentationSize.ToSize().Height);
 }
예제 #11
0
 public static void Pause(VideoHandle handle)
 {
     handle.Player.Pause();
 }
예제 #12
0
 public static double GetDuration(VideoHandle handle)
 {
     return(handle.Asset.Duration.Seconds);
 }
예제 #13
0
 public static int GetHeight(VideoHandle handle)
 {
     return((int)handle.PlayerItem.PresentationSize.ToRoundedCGSize().Height);
 }
예제 #14
0
 public static int GetWidth(VideoHandle handle)
 {
     return((int)handle.PlayerItem.PresentationSize.ToRoundedCGSize().Width);
 }
예제 #15
0
 public static void SetPosition(VideoHandle handle, double position)
 {
     handle.PlayerItem.Seek(CMTime.FromSeconds(position, 1000));
 }
예제 #16
0
 public static double GetPosition(VideoHandle handle)
 {
     return(handle.PlayerItem.CurrentTime.Seconds);
 }
예제 #17
0
 public static void Play(VideoHandle handle)
 {
     handle.Player.Play();
 }
예제 #18
0
 public static bool HasNewPixelBuffer(VideoHandle handle)
 {
     return(handle.Output.HasNewPixelBufferForItemTime(handle.PlayerItem.CurrentTime));
 }
예제 #19
0
 MonoImpl(string uri, Action loaded, Action <string> error)
 {
     _handle = VideoImpl.Create(uri, loaded, error);
 }
예제 #20
0
 public static int GetWidth(VideoHandle handle)
 {
     return(handle.PlayerItem.PresentationSize.ToSize().Width);
 }