gyorgy@0: using System; gyorgy@0: using System.Collections.Generic; gyorgy@0: using System.Linq; gyorgy@0: using System.Net; gyorgy@0: using System.Windows; gyorgy@0: using System.Windows.Controls; gyorgy@0: using System.Windows.Documents; gyorgy@0: using System.Windows.Input; gyorgy@0: using System.Windows.Media; gyorgy@0: using System.Windows.Media.Animation; gyorgy@0: using System.Windows.Shapes; gyorgy@0: using System.Windows.Browser; gyorgy@0: using System.Globalization; gyorgy@0: gyorgy@0: gyorgy@0: namespace SilverlightMediaElement gyorgy@0: { gyorgy@0: [ScriptableType] gyorgy@0: public partial class MainPage : UserControl gyorgy@0: { gyorgy@0: System.Windows.Threading.DispatcherTimer _timer; gyorgy@0: gyorgy@0: // work arounds for src, load(), play() compatibility gyorgy@0: bool _isLoading = false; gyorgy@0: bool _isAttemptingToPlay = false; gyorgy@0: gyorgy@0: // variables gyorgy@0: string _mediaUrl; gyorgy@0: string _preload; gyorgy@0: string _htmlid; gyorgy@0: bool _autoplay = false; gyorgy@0: bool _debug = false; gyorgy@0: int _width = 0; gyorgy@0: int _height = 0; gyorgy@0: int _timerRate = 0; gyorgy@0: double _bufferedBytes = 0; gyorgy@0: double _bufferedTime = 0; gyorgy@0: double _volume = 1; gyorgy@0: int _videoWidth = 0; gyorgy@0: int _videoHeight = 0; gyorgy@0: gyorgy@0: // state gyorgy@0: bool _isPaused = true; gyorgy@0: bool _isEnded = false; gyorgy@0: gyorgy@0: // dummy gyorgy@0: bool _firedCanPlay = false; gyorgy@0: gyorgy@0: public MainPage(IDictionary initParams) gyorgy@0: { gyorgy@0: InitializeComponent(); gyorgy@0: gyorgy@0: HtmlPage.RegisterScriptableObject("MediaElementJS", this); gyorgy@0: gyorgy@0: gyorgy@0: // add events gyorgy@0: media.BufferingProgressChanged += new RoutedEventHandler(media_BufferingProgressChanged); gyorgy@0: media.DownloadProgressChanged += new RoutedEventHandler(media_DownloadProgressChanged); gyorgy@0: media.CurrentStateChanged += new RoutedEventHandler(media_CurrentStateChanged); gyorgy@0: media.MediaEnded += new RoutedEventHandler(media_MediaEnded); gyorgy@0: media.MediaFailed += new EventHandler(media_MediaFailed); gyorgy@0: media.MediaOpened += new RoutedEventHandler(media_MediaOpened); gyorgy@0: gyorgy@0: // get parameters gyorgy@0: if (initParams.ContainsKey("id")) gyorgy@0: _htmlid = initParams["id"]; gyorgy@0: if (initParams.ContainsKey("file")) gyorgy@0: _mediaUrl = initParams["file"]; gyorgy@0: if (initParams.ContainsKey("autoplay") && initParams["autoplay"] == "true") gyorgy@0: _autoplay = true; gyorgy@0: if (initParams.ContainsKey("debug") && initParams["debug"] == "true") gyorgy@0: _debug = true; gyorgy@0: if (initParams.ContainsKey("preload")) gyorgy@0: _preload = initParams["preload"].ToLower(); gyorgy@0: else gyorgy@0: _preload = ""; gyorgy@0: gyorgy@0: if (!(new string[] { "none", "metadata", "auto" }).Contains(_preload)){ gyorgy@0: _preload = "none"; gyorgy@0: } gyorgy@0: gyorgy@0: if (initParams.ContainsKey("width")) gyorgy@0: Int32.TryParse(initParams["width"], out _width); gyorgy@0: if (initParams.ContainsKey("height")) gyorgy@0: Int32.TryParse(initParams["height"], out _height); gyorgy@0: if (initParams.ContainsKey("timerate")) gyorgy@0: Int32.TryParse(initParams["timerrate"], out _timerRate); gyorgy@0: if (initParams.ContainsKey("startvolume")) gyorgy@0: Double.TryParse(initParams["startvolume"], out _volume); gyorgy@0: gyorgy@0: if (_timerRate == 0) gyorgy@0: _timerRate = 250; gyorgy@0: gyorgy@0: // timer gyorgy@0: _timer = new System.Windows.Threading.DispatcherTimer(); gyorgy@0: _timer.Interval = new TimeSpan(0, 0, 0, 0, _timerRate); // 200 Milliseconds gyorgy@0: _timer.Tick += new EventHandler(timer_Tick); gyorgy@0: _timer.Stop(); gyorgy@0: gyorgy@0: //_mediaUrl = "http://local.mediaelement.com/media/jsaddington.mp4"; gyorgy@0: //_autoplay = true; gyorgy@0: gyorgy@0: // set stage and media sizes gyorgy@0: if (_width > 0) gyorgy@0: LayoutRoot.Width = media.Width = this.Width = _width; gyorgy@0: if (_height > 0) gyorgy@0: LayoutRoot.Height = media.Height = this.Height = _height; gyorgy@0: gyorgy@0: // debug gyorgy@0: textBox1.Visibility = (_debug) ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed; gyorgy@0: textBox1.IsEnabled = false; gyorgy@0: textBox1.Text = "id: " + _htmlid + "\n" + gyorgy@0: "file: " + _mediaUrl + "\n"; gyorgy@0: gyorgy@0: gyorgy@0: media.AutoPlay = _autoplay; gyorgy@0: media.Volume = _volume; gyorgy@0: if (!String.IsNullOrEmpty(_mediaUrl)) { gyorgy@0: setSrc(_mediaUrl); gyorgy@0: if (_autoplay || _preload != "none") gyorgy@0: loadMedia(); gyorgy@0: } gyorgy@0: gyorgy@0: media.MouseLeftButtonUp += new MouseButtonEventHandler(media_MouseLeftButtonUp); gyorgy@0: gyorgy@0: // full screen settings gyorgy@0: Application.Current.Host.Content.FullScreenChanged += new EventHandler(DisplaySizeInformation); gyorgy@0: Application.Current.Host.Content.Resized += new EventHandler(DisplaySizeInformation); gyorgy@0: FullscreenButton.Visibility = System.Windows.Visibility.Collapsed; gyorgy@0: gyorgy@0: // send out init call gyorgy@0: //HtmlPage.Window.Invoke("html5_MediaPluginBridge_initPlugin", new object[] {_htmlid}); gyorgy@0: try gyorgy@0: { gyorgy@0: HtmlPage.Window.Eval("mejs.MediaPluginBridge.initPlugin('" + _htmlid + "');"); gyorgy@0: } gyorgy@0: catch { } gyorgy@0: } gyorgy@0: gyorgy@0: void media_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { gyorgy@0: SendEvent("click"); gyorgy@0: } gyorgy@0: gyorgy@0: void media_MediaOpened(object sender, RoutedEventArgs e) { gyorgy@0: gyorgy@0: _videoWidth = Convert.ToInt32(media.NaturalVideoWidth); gyorgy@0: _videoHeight = Convert.ToInt32(media.NaturalVideoHeight); gyorgy@0: gyorgy@0: SendEvent("loadedmetadata"); gyorgy@0: } gyorgy@0: gyorgy@0: void timer_Tick(object sender, EventArgs e) { gyorgy@0: SendEvent("timeupdate"); gyorgy@0: } gyorgy@0: gyorgy@0: void StartTimer() { gyorgy@0: _timer.Start(); gyorgy@0: } gyorgy@0: gyorgy@0: void StopTimer() { gyorgy@0: _timer.Stop(); gyorgy@0: } gyorgy@0: gyorgy@0: void WriteDebug(string text) { gyorgy@0: textBox1.Text += text + "\n"; gyorgy@0: } gyorgy@0: gyorgy@0: void media_MediaFailed(object sender, ExceptionRoutedEventArgs e) { gyorgy@0: SendEvent(e.ToString()); gyorgy@0: } gyorgy@0: gyorgy@0: void media_MediaEnded(object sender, RoutedEventArgs e) { gyorgy@0: _isEnded = true; gyorgy@0: _isPaused = false; gyorgy@0: SendEvent("ended"); gyorgy@0: StopTimer(); gyorgy@0: } gyorgy@0: gyorgy@0: void media_CurrentStateChanged(object sender, RoutedEventArgs e) { gyorgy@0: gyorgy@0: WriteDebug("state:" + media.CurrentState.ToString()); gyorgy@0: gyorgy@0: switch (media.CurrentState) gyorgy@0: { gyorgy@0: case MediaElementState.Opening: gyorgy@0: SendEvent("loadstart"); gyorgy@0: break; gyorgy@0: case MediaElementState.Playing: gyorgy@0: _isEnded = false; gyorgy@0: _isPaused = false; gyorgy@0: _isAttemptingToPlay = false; gyorgy@0: StartTimer(); gyorgy@0: gyorgy@0: gyorgy@0: SendEvent("play"); gyorgy@0: SendEvent("playing"); gyorgy@0: break; gyorgy@0: gyorgy@0: case MediaElementState.Paused: gyorgy@0: _isEnded = false; gyorgy@0: _isPaused = true; gyorgy@0: gyorgy@0: // special settings to allow play() to work gyorgy@0: _isLoading = false; gyorgy@0: WriteDebug("paused event, " + _isAttemptingToPlay); gyorgy@0: if (_isAttemptingToPlay) { gyorgy@0: this.playMedia(); gyorgy@0: } gyorgy@0: gyorgy@0: StopTimer(); gyorgy@0: SendEvent("paused"); gyorgy@0: break; gyorgy@0: case MediaElementState.Stopped: gyorgy@0: _isEnded = false; gyorgy@0: _isPaused = true; gyorgy@0: StopTimer(); gyorgy@0: SendEvent("paused"); gyorgy@0: break; gyorgy@0: case MediaElementState.Buffering: gyorgy@0: SendEvent("progress"); gyorgy@0: break; gyorgy@0: } gyorgy@0: gyorgy@0: } gyorgy@0: gyorgy@0: void media_BufferingProgressChanged(object sender, RoutedEventArgs e) { gyorgy@0: _bufferedTime = media.DownloadProgress * media.NaturalDuration.TimeSpan.TotalSeconds; gyorgy@0: _bufferedBytes = media.BufferingProgress; gyorgy@0: gyorgy@0: gyorgy@0: SendEvent("progress"); gyorgy@0: } gyorgy@0: gyorgy@0: void media_DownloadProgressChanged(object sender, RoutedEventArgs e) { gyorgy@0: _bufferedTime = media.DownloadProgress * media.NaturalDuration.TimeSpan.TotalSeconds; gyorgy@0: _bufferedBytes = media.BufferingProgress; gyorgy@0: gyorgy@0: if (!_firedCanPlay) { gyorgy@0: SendEvent("loadeddata"); gyorgy@0: SendEvent("canplay"); gyorgy@0: _firedCanPlay = true; gyorgy@0: } gyorgy@0: gyorgy@0: SendEvent("progress"); gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: void SendEvent(string name) { gyorgy@0: /* gyorgy@0: * INVOKE gyorgy@0: HtmlPage.Window.Invoke("html5_MediaPluginBridge_fireEvent", gyorgy@0: _htmlid, gyorgy@0: name, gyorgy@0: @"'{" + gyorgy@0: @"""name"": """ + name + @"""" + gyorgy@0: @", ""currentTime"":" + (media.Position.TotalSeconds).ToString() + @"" + gyorgy@0: @", ""duration"":" + (media.NaturalDuration.TimeSpan.TotalSeconds).ToString() + @"" + gyorgy@0: @", ""paused"":" + (_isEnded).ToString().ToLower() + @"" + gyorgy@0: @", ""muted"":" + (media.IsMuted).ToString().ToLower() + @"" + gyorgy@0: @", ""ended"":" + (_isPaused).ToString().ToLower() + @"" + gyorgy@0: @", ""volume"":" + (media.Volume).ToString() + @"" + gyorgy@0: @", ""bufferedBytes"":" + (_bufferedBytes).ToString() + @"" + gyorgy@0: @", ""bufferedTime"":" + (_bufferedTime).ToString() + @"" + gyorgy@0: @"}'"); gyorgy@0: */ gyorgy@0: gyorgy@0: /* gyorgy@0: * EVAL gyorgy@0: HtmlPage.Window.Eval("mejs.MediaPluginBridge.fireEvent('" + _htmlid + "','" + name + "'," + gyorgy@0: @"{" + gyorgy@0: @"""name"": """ + name + @"""" + gyorgy@0: @", ""currentTime"":" + (media.Position.TotalSeconds).ToString() + @"" + gyorgy@0: @", ""duration"":" + (media.NaturalDuration.TimeSpan.TotalSeconds).ToString() + @"" + gyorgy@0: @", ""paused"":" + (_isEnded).ToString().ToLower() + @"" + gyorgy@0: @", ""muted"":" + (media.IsMuted).ToString().ToLower() + @"" + gyorgy@0: @", ""ended"":" + (_isPaused).ToString().ToLower() + @"" + gyorgy@0: @", ""volume"":" + (media.Volume).ToString() + @"" + gyorgy@0: @", ""bufferedBytes"":" + (_bufferedBytes).ToString() + @"" + gyorgy@0: @", ""bufferedTime"":" + (_bufferedTime).ToString() + @"" + gyorgy@0: @"});"); gyorgy@0: * */ gyorgy@0: gyorgy@0: // setTimeout gyorgy@0: try { gyorgy@0: CultureInfo invCulture = CultureInfo.InvariantCulture; gyorgy@0: gyorgy@0: HtmlPage.Window.Invoke("setTimeout", "mejs.MediaPluginBridge.fireEvent('" + _htmlid + "','" + name + "'," + gyorgy@0: @"{" + gyorgy@0: @"""name"": """ + name + @"""" + gyorgy@0: @", ""currentTime"":" + (media.Position.TotalSeconds).ToString(invCulture) + @"" + gyorgy@0: @", ""duration"":" + (media.NaturalDuration.TimeSpan.TotalSeconds).ToString(invCulture) + @"" + gyorgy@0: @", ""paused"":" + (_isPaused).ToString().ToLower() + @"" + gyorgy@0: @", ""muted"":" + (media.IsMuted).ToString().ToLower() + @"" + gyorgy@0: @", ""ended"":" + (_isEnded).ToString().ToLower() + @"" + gyorgy@0: @", ""volume"":" + (media.Volume).ToString(invCulture) + @"" + gyorgy@0: @", ""bufferedBytes"":" + (_bufferedBytes).ToString(invCulture) + @"" + gyorgy@0: @", ""bufferedTime"":" + (_bufferedTime).ToString(invCulture) + @"" + gyorgy@0: @", ""videoWidth"":" + (_videoWidth).ToString() + @"" + gyorgy@0: @", ""videoHeight"":" + (_videoHeight).ToString() + @"" + gyorgy@0: @"});", 0); gyorgy@0: } catch { } gyorgy@0: gyorgy@0: } gyorgy@0: gyorgy@0: /* HTML5 wrapper methods */ gyorgy@0: [ScriptableMember] gyorgy@0: public void playMedia() { gyorgy@0: WriteDebug("method:play " + media.CurrentState); gyorgy@0: gyorgy@0: // sometimes people forget to call load() first gyorgy@0: if (_mediaUrl != "" && media.Source == null) { gyorgy@0: _isAttemptingToPlay = true; gyorgy@0: loadMedia(); gyorgy@0: } gyorgy@0: gyorgy@0: // store and trigger with the state change above gyorgy@0: if (media.CurrentState == MediaElementState.Closed && _isLoading) { gyorgy@0: WriteDebug("storing _isAttemptingToPlay "); gyorgy@0: _isAttemptingToPlay = true; gyorgy@0: } gyorgy@0: gyorgy@0: media.Play(); gyorgy@0: _isEnded = false; gyorgy@0: _isPaused = false; gyorgy@0: gyorgy@0: //StartTimer(); gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void pauseMedia() { gyorgy@0: WriteDebug("method:pause " + media.CurrentState); gyorgy@0: gyorgy@0: _isEnded = false; gyorgy@0: _isPaused = true; gyorgy@0: gyorgy@0: media.Pause(); gyorgy@0: StopTimer(); gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void loadMedia() { gyorgy@0: _isLoading = true; gyorgy@0: _firedCanPlay = false; gyorgy@0: gyorgy@0: WriteDebug("method:load " + media.CurrentState); gyorgy@0: WriteDebug(" - " + _mediaUrl.ToString()); gyorgy@0: gyorgy@0: media.Source = new Uri(_mediaUrl, UriKind.Absolute); gyorgy@0: //media.Play(); gyorgy@0: //media.Stop(); gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void stopMedia() { gyorgy@0: WriteDebug("method:stop " + media.CurrentState); gyorgy@0: gyorgy@0: _isEnded = true; gyorgy@0: _isPaused = false; gyorgy@0: gyorgy@0: media.Stop(); gyorgy@0: StopTimer(); gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void setVolume(Double volume) { gyorgy@0: WriteDebug("method:setvolume: " + volume.ToString()); gyorgy@0: gyorgy@0: media.Volume = volume; gyorgy@0: gyorgy@0: SendEvent("volumechange"); gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void setMuted(bool isMuted) { gyorgy@0: WriteDebug("method:setmuted: " + isMuted.ToString()); gyorgy@0: gyorgy@0: media.IsMuted = isMuted; gyorgy@0: gyorgy@0: SendEvent("volumechange"); gyorgy@0: gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void setCurrentTime(Double position) { gyorgy@0: WriteDebug("method:setCurrentTime: " + position.ToString()); gyorgy@0: gyorgy@0: int milliseconds = Convert.ToInt32(position * 1000); gyorgy@0: gyorgy@0: SendEvent("seeking"); gyorgy@0: media.Position = new TimeSpan(0, 0, 0, 0, milliseconds); gyorgy@0: SendEvent("seeked"); gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void setSrc(string url) { gyorgy@0: _mediaUrl = url; gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void setFullscreen(bool goFullscreen) { gyorgy@0: gyorgy@0: FullscreenButton.Visibility = System.Windows.Visibility.Visible; gyorgy@0: } gyorgy@0: gyorgy@0: [ScriptableMember] gyorgy@0: public void setVideoSize(int width, int height) { gyorgy@0: this.Width = media.Width = width; gyorgy@0: this.Height = media.Height = height; gyorgy@0: } gyorgy@0: gyorgy@0: private void FullscreenButton_Click(object sender, RoutedEventArgs e) { gyorgy@0: Application.Current.Host.Content.IsFullScreen = true; gyorgy@0: FullscreenButton.Visibility = System.Windows.Visibility.Collapsed; gyorgy@0: } gyorgy@0: gyorgy@0: private void DisplaySizeInformation(Object sender, EventArgs e) { gyorgy@0: this.Width = LayoutRoot.Width = media.Width = Application.Current.Host.Content.ActualWidth; gyorgy@0: this.Height = LayoutRoot.Height = media.Height = Application.Current.Host.Content.ActualHeight; gyorgy@0: } gyorgy@0: gyorgy@0: } gyorgy@0: }