2015-11-04 85 views
2

我們使用​​構建應用程序在Xamarin。在應用程序中,我們需要播放視頻,所以我們爲此編寫了一些代碼。但是,該視頻並未播放,Android上的應用程序崩潰,同時拋出一個通用錯誤。與Xamarin播放視頻格式

這是代碼:

VideoContainer.cs

using System; 
using Xamarin.Forms; 
using System.Collections.Generic; 

namespace MyApp 
{ 
    public class VideoView : View 
    { 
     public Action StopAction; 
     public VideoView() 
     { 
      Console.WriteLine("VideoView loaded"); 
     } 

     public static readonly BindableProperty FileSourceProperty = 
      BindableProperty.Create<VideoView,string>(
       p => p.FileSource,string.Empty); 

     public string FileSource { 
      get { return (string)GetValue (FileSourceProperty); } 
      set { SetValue (FileSourceProperty, value); } 
     } 

     public void Stop(){ 
      if(StopAction != null) 
       StopAction(); 
     } 
    } 
} 

VideoViewRender.cs

using System.Text; 

using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Widget; 
using Xamarin.Forms; 
using Xamarin.Forms.Platform.Android; 
using Android.Media; 
using Android.Content.Res; 
using Java.Lang; 
using MyApp.Droid; 

[assembly: ExportRenderer(typeof(VideoView), typeof(VideoViewRenderer))] 
// 
namespace MyApp.Droid 
{ 
    public class VideoViewRenderer : ViewRenderer 
    { 
     VideoView videoview; 
     MediaPlayer player; 
     MediaController mediaController; 
     Handler handler = new Handler(); 
     public VideoViewRenderer() 
     { 
      Console.WriteLine("VideoViewRenderer loaded"); 
     } 

     public void SurfaceChanged(ISurfaceHolder holder, global::Android.Graphics.Format format, int width, int height) 
     { 

     } 

     public void SurfaceDestroyed(ISurfaceHolder holder) 
     { 

     } 

     void play(string fullPath) 
     { 
      AssetFileDescriptor afd = Forms.Context.Assets.OpenFd(fullPath); 
      if (afd != null) 
      { 

       player.SetDataSource(afd.FileDescriptor, afd.StartOffset, afd.Length); 
       player.Prepare(); 
       player.Start(); 
       Control.Layout(0, 200, 400, 600); 
       player.Pause(); 


      } 
     } 

     public void SurfaceCreated(ISurfaceHolder holder) 
     { 
      player.SetDisplay(holder); 
     } 

     public override bool OnTouchEvent(MotionEvent e) 
     { 
      mediaController.Show(); 
      return false; 
     } 

     //--MediaPlayerControl methods---------------------------------------------------- 
     public void Start() 
     { 
      player.Start(); 
     } 


     public void Pause() 
     { 
      player.Pause(); 
     } 

     public int Duration 
     { 
      get 
      { 
       return player.Duration; 
      } 
     } 

     public int CurrentPosition 
     { 
      get 
      { 
       return player.CurrentPosition; 
      } 
     } 

     public void SeekTo(int i) 
     { 
      player.SeekTo(i); 
     } 

     public bool IsPlaying 
     { 
      get 
      { 
       return player.IsPlaying; 
      } 
     } 

     public int BufferPercentage 
     { 
      get 
      { 
       return 0; 
      } 
     } 

     public int AudioSessionId 
     { 
      get 
      { 
       return 0; 
      } 
     } 

     public bool CanPause() 
     { 
      return true; 
     } 

     public bool CanSeekBackward() 
     { 
      return true; 
     } 

     public bool CanSeekForward() 
     { 
      return true; 
     } 
     //-------------------------------------------------------------------------------- 

    } 
} 

什麼情況是,VideoView loaded登錄到控制檯,但VideoViewRenderer loaded不是。我們從the Xamarin forum獲得了此代碼,但無法成功實施。我們做錯了什麼?

回答

-1

這是比較容易查看此樣品。

https://github.com/logikonline/xamarin-amccorma

享受!

編輯:請參閱此實現最初由https://github.com/amccorma/xamarin-amccorma

[assembly: ExportRenderer(typeof(MyVideoPlayer), typeof(VideoSamples.Droid.MyVideoPlayerRenderer))] 
namespace VideoSamples.Droid 
{ 
    public class MyVideoPlayerRenderer : ViewRenderer<MyVideoPlayer, Android.Widget.RelativeLayout> 
    { 
     private MediaController _MCController; 
     private MyVideoView _MyVideoView; 
     private bool _AttachedController; 
     private Android.Widget.RelativeLayout _MainLayout; 

     public MyVideoPlayerRenderer() 
     { 
      this._AttachedController = false; 
     } 

     protected override void Dispose (bool disposing) 
     { 
      if (this._MCController != null && this._MyVideoView != null) { 
       this._MyVideoView.SetMediaController (null); 
      } 
      if (this._MCController != null) { 
       this._MCController.Dispose(); 
       this._MCController = null; 
      } 

      if (this._MyVideoView != null) { 
       this._MyVideoView.StopPlayback(); 
       this._MyVideoView.Dispose(); 
       this._MyVideoView = null; 
      } 
      base.Dispose (disposing); 
     } 

     protected override void OnElementChanged (ElementChangedEventArgs<MyVideoPlayer> e) 
     { 
      base.OnElementChanged (e); 
      if (this.Control == null) { 
       var layoutInflater = (LayoutInflater)Context.GetSystemService(global::Android.Content.Context.LayoutInflaterService); 
       this._MainLayout = (Android.Widget.RelativeLayout)layoutInflater.Inflate (VideoSamples.Droid.Resource.Layout.VideoLayout, null);  
       SetNativeControl (this._MainLayout); 
      } 

      this._MyVideoView = this.Control.FindViewById<MyVideoView>(VideoSamples.Droid.Resource.Id.videoView1); 


      // full screen hack? 
      ResizeScreen (true); //this.Element.FullScreen); 

      // must set reference to root element 
      this._MyVideoView.ParentElement = this.Element; 

      // pick controller 
      this._MCController = new MediaController (this.Context); 
      this._MCController.SetMediaPlayer (this._MyVideoView); 

      if (this.Element.AddVideoController) {    
       this._AttachedController = true; 
       this._MyVideoView.SetMediaController (this._MCController); 
      } else { 
       this._AttachedController = false; 
      } 

      // load file 
      this._MyVideoView.LoadFile (this.Element.FileSource); 

      if (this.Element.AutoPlay) { 
       // play if set to autoplay on load 
       this._MyVideoView.Play(); 
      } 
     } 

     protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e) 
     { 
      base.OnElementPropertyChanged (sender, e); 
      var source = this.Element; 
      if (source != null && this._MyVideoView != null) { 
       if (e.PropertyName == MyVideoPlayer.SeekProperty.PropertyName) { 
        this._MyVideoView.SeekTo ((int)this.Element.Seek); 
       } else if (e.PropertyName == MyVideoPlayer.FileSourceProperty.PropertyName) { 

        // load the play file 
        this._MyVideoView.LoadFile (this.Element.FileSource); 
        this._MyVideoView.Play(); 
       } else if (e.PropertyName == MyVideoPlayer.AddVideoControllerProperty.PropertyName) { 
        if (source.AddVideoController && this._AttachedController == false) { 
         this._MyVideoView.SetMediaController (this._MCController); 
        } else { 
         this._MyVideoView.SetMediaController (null); 
        } 
       } else if (e.PropertyName == MyVideoPlayer.FullScreenProperty.PropertyName) { 
        ResizeScreen (source.FullScreen); 
       } else if (e.PropertyName == "OrientationChanged") { 
        ResizeScreen (source.FullScreen); 
       } else if (e.PropertyName == MyVideoPlayer.ActionBarHideProperty.PropertyName) { 
        ResizeScreen (source.FullScreen); 
       } else if (e.PropertyName == MyVideoPlayer.PlayerActionProperty.PropertyName) { 
        if (source.PlayerAction == VideoState.PAUSE) { 
         this._MyVideoView.Pause(); 
        } else if (source.PlayerAction == VideoState.PLAY) { 
         this._MyVideoView.Play(); 
        } else if (source.PlayerAction == VideoState.RESTART) { 
         this._MyVideoView.SeekTo (0); 
         this._MyVideoView.Play(); 
        } else if (source.PlayerAction == VideoState.STOP) { 
         this._MyVideoView.StopPlayback(); 
        } 
       } 
      } 
     } 

     private void ResizeScreen(bool fullscreen) 
     { 
      var a = this.Context as Activity; 
      if (this.Element.ActionBarHide) { 
       a.ActionBar.Hide(); 
      } else { 
       a.ActionBar.Show(); 
      } 
      if (fullscreen) { 
       var p = this._MyVideoView.LayoutParameters as Android.Widget.RelativeLayout.LayoutParams; 
       p.Height = Android.Widget.RelativeLayout.LayoutParams.FillParent; 

       // added works ok for rotation 
       var view = a.Window.DecorView; 
       Rect rect = new Rect(); 
       view.GetWindowVisibleDisplayFrame (rect); 

       var width = (int)this.Element.ContentWidth; 
       var height = (this.Element.ActionBarHide) ? rect.Height() : (int)this.Element.ContentHeight; 
       var holder = this._MyVideoView.Holder; 

       p.Height = height; 
       p.Width = width; 

       holder.SetFixedSize (width, height); 
       // end 

       p.AlignWithParent = true; 
       this._MyVideoView.LayoutParameters = p; 

      } else { 
       var p = this._MyVideoView.LayoutParameters as Android.Widget.RelativeLayout.LayoutParams; 
       if (this.Element.HeightRequest > 0 || this.Element.WidthRequest > 0) { 
        if (this.Element.HeightRequest > 0) { 
         p.Height = (int)this.Element.HeightRequest; 
        } 
        if (this.Element.WidthRequest > 0) { 
         p.Width = (int)this.Element.WidthRequest; 
        } 
        this._MyVideoView.LayoutParameters = p; 
       } 
       p.AlignWithParent = false; 
       this._MyVideoView.LayoutParameters = p; 
      } 

      InvalidLayout(); 
     } 

     private void InvalidLayout() 
     { 
      if (this.Element.Orientation == MyVideoPlayer.ScreenOrientation.LANDSCAPE) { 

      } 
      Xamarin.Forms.Device.BeginInvokeOnMainThread (() => { 

       this._MyVideoView.ForceLayout(); 
       this._MyVideoView.RequestLayout(); 
       this._MyVideoView.Holder.SetSizeFromLayout(); 
       this._MyVideoView.Invalidate(); 

      }); 
     } 
    } 
} 
+0

請注意,張貼鏈接到您自己的GitHub的項目,但沒有附帶代碼講解如何使用它可以被看作是[自我推銷(http://meta.stackexchange.com/q/57497/284827 )由一些。 –

+0

對不起 - 我分叉它一會兒回來,不是想邀功。 –

0

做我覺得你[assembly:...]得到錯誤VideoView

有可能ExportRenderer得到Android.VideoView

你應該得到[assembly: ExportRenderer(typeof(MyApp.VideoView), typeof(MyApp.Droid.VideoView))]