bool SeekToTrack (PlayBin2 playbin, int track) { Format format = Format.Undefined; CddaBaseSrc cdda_src = null; State state; format = Util.FormatGetByNick ("track"); if (format == Format.Undefined) { return false; } playbin.GetState (out state, 0); if (state < State.Paused) { // We can only seek if the pipeline is playing or paused, otherwise // we just allow playbin to do its thing, which will re-start the // device and start at the desired track return false; } cdda_src = GetCddaSource (playbin); if (cdda_src == null) { return false; } if (playbin.Seek (1.0, format, SeekFlags.Flush, SeekType.Set, track - 1, SeekType.None, -1)) { Log.DebugFormat ("cdda: seeking to track {0}, avoiding playbin", track); return true; } return false; }
public PlayerEngine () { Console.WriteLine ("Gst# PlayerEngine ctor - completely experimental, still a WIP"); Gst.Application.Init (); pipeline = new Pipeline (); playbin = new PlayBin2 (); pipeline.Add (playbin); pipeline.Bus.AddWatch (OnBusMessage); Banshee.ServiceStack.Application.RunTimeout (200, delegate { OnEventChanged (PlayerEvent.Iterate); return true; }); OnStateChanged (PlayerState.Ready); }
public AudioPlayer() { // These environment variables are necessary to locate GStreamer libraries, and to stop it from loading // wrong libraries installed elsewhere on the system. var directoryName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); if (directoryName != null) { string apppath = directoryName.Remove(0, 6); string pluginPath = apppath + @"\gstreamer\bin\plugins"; Environment.SetEnvironmentVariable("GST_PLUGIN_PATH", pluginPath); Environment.SetEnvironmentVariable("GST_PLUGIN_SYSTEM_PATH", ""); string pathVariable = @"C:\Windows;" + apppath + @"\gstreamer\lib;" + apppath + @"\gstreamer\bin;" + Environment.GetEnvironmentVariable("PATH"); Environment.SetEnvironmentVariable("PATH", pathVariable); Environment.SetEnvironmentVariable("GST_REGISTRY", apppath + @"\gstreamer\bin\registry.bin"); // These are for saving debug information. Environment.SetEnvironmentVariable("GST_DEBUG", "*:3"); Environment.SetEnvironmentVariable("GST_DEBUG_FILE", "GstreamerLog.txt"); Environment.SetEnvironmentVariable("GST_DEBUG_DUMP_DOT_DIR", apppath); } Application.Init(); _playBin = new PlayBin2("_playBin"); Element audioSink = SelectAudioSink(); _playBin.AudioSink = audioSink; _playBin.Bus.AddWatch(OnBusMessage); // TODO: implement gapless playback (wait for gstreamer fix?) /*_playBin.AboutToFinish += (o, args) => { if (_currentTrackIndex + 1 >= _trackArray.Length) return; OnTrackChanged(new TrackChangedHandlerArgs { NewTrack = _trackArray[_currentTrackIndex + 1], OldTrack = _trackArray[_currentTrackIndex] }); _playBin.Uri = PathStringToUri(_trackArray[++_currentTrackIndex].Path); };*/ _trackArray = new Track[0]; _playBin.SetState(State.Ready); }
public PlayerEngine () { Console.WriteLine ("Gst# PlayerEngine ctor - completely experimental, still a WIP"); Gst.Application.Init (); //Making early-bound elements pipeline = new Pipeline (); playbin = new PlayBin2 (); audiobin = new MyBinType ("audiobin"); filterbin = new BinList<Element> ("filterbin"); //Making late-bound elements (not currently bound by gst-sharp) audiosink = ElementFactory.Make ("gconfaudiosink", "thesink"); if (audiosink == null) audiosink = ElementFactory.Make ("autoaudiosink", "thesink"); queue = ElementFactory.Make ("queue", "audioqueue"); //Adding, linking, and padding filterbin.Add (queue); audiobin.Add (filterbin.GetBin (), audiosink); filterbin.GetSourceGhostPad ().Link (audiosink.GetStaticPad ("sink")); audiobinsink.SetTarget (filterbin.GetSinkGhostPad ()); audiobin.AddPadHack (audiobinsink); playbin.AudioSink = audiobin; pipeline.Add (playbin); pipeline.Bus.AddWatch (OnBusMessage); Banshee.ServiceStack.Application.RunTimeout (200, delegate { OnEventChanged (PlayerEvent.Iterate); return true; }); OnStateChanged (PlayerState.Ready); }
public PlayerEngine () { Log.InformationFormat ("GStreamer# {0} Initializing; {1}.{2}", typeof (Gst.Version).Assembly.GetName ().Version, Gst.Version.Description, Gst.Version.Nano); // Setup the gst plugins/registry paths if running Windows if (PlatformDetection.IsWindows) { var gst_paths = new string [] { Hyena.Paths.Combine (Hyena.Paths.InstalledApplicationPrefix, "gst-plugins") }; Environment.SetEnvironmentVariable ("GST_PLUGIN_PATH", String.Join (";", gst_paths)); Environment.SetEnvironmentVariable ("GST_PLUGIN_SYSTEM_PATH", ""); Environment.SetEnvironmentVariable ("GST_DEBUG", "1"); string registry = Hyena.Paths.Combine (Hyena.Paths.ApplicationData, "registry.bin"); if (!System.IO.File.Exists (registry)) { System.IO.File.Create (registry).Close (); } Environment.SetEnvironmentVariable ("GST_REGISTRY", registry); //System.Environment.SetEnvironmentVariable ("GST_REGISTRY_FORK", "no"); Log.DebugFormat ("GST_PLUGIN_PATH = {0}", Environment.GetEnvironmentVariable ("GST_PLUGIN_PATH")); } Gst.Application.Init (); pipeline = new Pipeline (); playbin = new PlayBin2 (); pipeline.Add (playbin); // Remember the volume from last time Volume = (ushort)PlayerEngineService.VolumeSchema.Get (); playbin.AddNotification ("volume", OnVolumeChanged); pipeline.Bus.AddWatch (OnBusMessage); OnStateChanged (PlayerState.Ready); }
public void NavigateToMenu (PlayBin2 playbin) { if (Navigation == null) { FindNavigation (playbin); } if (Navigation != null) { Navigation.SendCommand (NavigationCommand.DvdMenu); } }
public void NotifyMouseButtonReleased (PlayBin2 playbin, int button, double x, double y) { if (Navigation == null) { FindNavigation (playbin); } if (Navigation != null) { Navigation.SendMouseEvent ("mouse-button-release", button, x, y); } }
public void NotifyMouseMove (PlayBin2 playbin, double x, double y) { if (Navigation == null) { FindNavigation (playbin); } if (Navigation != null) { Navigation.SendMouseEvent ("mouse-move", 0, x, y); } }
public void FindNavigation (PlayBin2 playbin) { Element video_sink = null; Element navigation = null; Navigation previous_navigation; previous_navigation = Navigation; video_sink = playbin ["video-sink"] as Element; if (video_sink == null) { Navigation = null; if (previous_navigation != null) { previous_navigation = null; } } navigation = (video_sink is Bin) ? ((Bin)video_sink).GetByInterface (typeof (NavigationAdapter)) : video_sink; Navigation = navigation as Navigation; }
void ButtonOpenClicked(object sender, EventArgs args) { FileChooserDialog dialog = new FileChooserDialog ("Open", this, FileChooserAction.Open, new object[] { "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept }); dialog.SetCurrentFolder (Environment.GetFolderPath (Environment.SpecialFolder.Personal)); if (dialog.Run () == (int) ResponseType.Accept) { _pipelineOK = false; if (_playbin != null) { _playbin.SetState (Gst.State.Null); } else { _playbin = new PlayBin2 (); } _scale.Value = 0; if (_playbin == null) Console.WriteLine ("Unable to create element 'playbin'"); _playbin.Bus.EnableSyncMessageEmission (); _playbin.Bus.AddSignalWatch (); _playbin.Bus.SyncMessage += delegate (object bus, SyncMessageArgs sargs) { Gst.Message msg = sargs.Message; if (msg == null || msg.Type != Gst.MessageType.Element || msg.Structure == null || msg.Structure.Name == null || !msg.Structure.Name.Equals ("prepare-xwindow-id")) return; Element src = msg.Src as Element; if (src == null) return; if (src.HasProperty ("force-aspect-ratio")) src["force-aspect-ratio"] = true; (src as XOverlay).XwindowId = _xWindowId; (src as XOverlay).HandleEvents (true); }; _playbin.Bus.Message += delegate (object bus, MessageArgs margs) { Message message = margs.Message; switch (message.Type) { case Gst.MessageType.Error: Enum err; string msg; message.ParseError (out err, out msg); Console.WriteLine (String.Format ("Error message: {0}", msg)); _pipelineOK = false; break; case Gst.MessageType.Eos: Console.WriteLine ("EOS"); break; } }; switch (System.Environment.OSVersion.Platform) { case PlatformID.Unix: _playbin["uri"] = "file://" + dialog.Filename; break; case PlatformID.Win32NT: case PlatformID.Win32S: case PlatformID.Win32Windows: case PlatformID.WinCE: _playbin["uri"] = "file:///" + dialog.Filename.Replace("\\","/"); break; } StateChangeReturn sret = _playbin.SetState (Gst.State.Playing); if (sret == StateChangeReturn.Async) { State state, pending; sret = _playbin.GetState (out state, out pending, Clock.Second * 5); } if (sret == StateChangeReturn.Success) { Console.WriteLine ("State change successful"); _pipelineOK = true; } else { Console.WriteLine ("State change failed for {0} ({1})\n", dialog.Filename, sret); } } dialog.Destroy (); }
public DvdManager (PlayBin2 playbin) { if (playbin != null) { playbin.AddNotification ("source", OnSourceChanged); } }
public VideoManager (PlayBin2 playbin) { this.playbin = playbin; }
public bool HandleURI (PlayBin2 playbin, string uri) { // Processes URIs like cdda://<track-number>#<device-node> and overrides // track transitioning through playbin if playback was already happening // from the device node by seeking directly to the track since the disc // is already spinning; playbin doesn't handle CDDA URIs with device nodes // so we have to handle setting the device property on GstCddaBaseSrc // through the notify::source signal on playbin string new_cdda_device; int p; if (playbin == null || String.IsNullOrEmpty (uri) || !uri.StartsWith ("cdda://")) { // Something is hosed or the URI isn't actually CDDA if (Device != null) { Log.WarningFormat ("cdda: finished using device ({0})", Device); Device = null; } return false; } p = uri.IndexOf ('#'); if (p == -1 || p + 2 > uri.Length) { // Unset the cached device node if the URI doesn't // have its own valid device node Device = null; Log.WarningFormat ("cdda: invalid device node in URI ({0})", uri); return false; } new_cdda_device = uri.Substring (p + 1); if (Device == null) { // If we weren't already playing from a CD, cache the // device and allow playbin to begin playing it Device = new_cdda_device; Log.DebugFormat ("cdda: storing device node for fast seeks ({0})", Device); return false; } if (new_cdda_device == Device) { // Parse the track number from the URI and seek directly to it // since we are already playing from the device; prevent playbin // from stopping/starting the CD, which can take many many seconds string track_str = uri.Substring (7, p - 7); int track_num; int.TryParse (track_str, out track_num); Log.DebugFormat ("cdda: fast seeking to track on already playing device ({0})", Device); return SeekToTrack (playbin, track_num); } // We were already playing some CD, but switched to a different device node, // so unset and re-cache the new device node and allow playbin to do its thing Log.DebugFormat ("cdda: switching devices for CDDA playback (from {0}, to {1})", Device, new_cdda_device); Device = new_cdda_device; return false; }
public void PlayAudioStream(string url) { if (_currentUrl == url && _playBin != null) { _playBin.SetState(State.Playing); return; } _currentUrl = url; if (_playBin != null) { _playBin.SetState(Gst.State.Null); _playBin.SetVolume(StreamVolumeFormat.Linear, _initialVolume); } url = String.Format("{0}?client_id={1}", url, SoundCloudRestClient.API_CLIENT_ID); Console.WriteLine(url); _playBin = ElementFactory.Make ("playbin2", "play") as PlayBin2; _playBin.Uri = url; _playBin.Bus.AddWatch ( new BusFunc( (bus, message) => { switch (message.Type) { case Gst.MessageType.Error: Enum err; string msg; message.ParseError (out err, out msg); Console.WriteLine ("Gstreamer error: {0}", msg); //loop.Quit (); break; case Gst.MessageType.Eos: Console.WriteLine ("Stream finished."); _playBin.SetState (Gst.State.Null); if (TrackEnded != null) TrackEnded (this, new EventArgs()); break; } return true; })); // Play the stream if (_playBin.CurrentState != State.Paused) _playBin.SetState(State.Playing); // Start rendering the waveform StartTimecodeUpdate(); }
void OnDeleteEvent(object sender, DeleteEventArgs args) { Gtk.Application.Quit (); if (_playbin != null) { _playbin.SetState (Gst.State.Null); _playbin.Dispose (); _playbin = null; } args.RetVal = true; }
public void ActivateCurrentMenu (PlayBin2 playbin) { if (Navigation == null) { FindNavigation (playbin); } if (Navigation != null) { Navigation.SendCommand (NavigationCommand.Activate); } }
public void GoToPreviousChapter (PlayBin2 playbin) { long index; Format format = Util.FormatGetByNick ("chapter"); playbin.QueryPosition (ref format, out index); playbin.Seek (1.0, format, SeekFlags.Flush, SeekType.Set, index - 1, SeekType.None, 0l); }
/// <summary> /// Polling thread. Pull buffer data from GST thread. /// </summary> void KeepPolling(){ while(isrunning){ switch (playerState) { case VideoPlayerState.STOPPED: break; case VideoPlayerState.LOADING: //get video width/height int w = 0, h = 0; //Query video information Gst.Buffer buf = appSink.PullBuffer(); if(buf != null){ Console.WriteLine(buf.Caps.ToString()); //string format = buf.Caps[0].GetValue("format").Val.ToString(); //Console.WriteLine("format: " + format); int.TryParse(buf.Caps[0].GetValue("width").Val.ToString(), out w); int.TryParse(buf.Caps[0].GetValue("height").Val.ToString(), out h); if (w * h != 0) { //Create decoded buffer lock (lockFrameBuf) { width = w; height = h; buffer = new byte[width * height * 3]; Marshal.Copy(buf.Data, buffer, 0, width * height * 3); isFrameNew = true; //Dispose handle to avoid memory leak //gst_mini_object_unref(buf.Handle); buf.Dispose(); } Console.WriteLine("PLAYING"); playerState = VideoPlayerState.PLAYING; continue; } } break; case VideoPlayerState.PLAYING: Gst.Buffer buf2 = appSink.PullBuffer(); if(buf2 != null){ lock(lockFrameBuf){ //Update buffer Marshal.Copy(buf2.Data, buffer, 0, width * height * 3); isFrameNew = true; //gst_mini_object_unref(buf2.Handle); //buf2.Dispose(); } buf2.Dispose(); }else{ lock (lockFrameBuf) { //Clear buffer buffer = new byte[width * height * 3]; } playerState = VideoPlayerState.STOPPED; Console.WriteLine("STOPPED"); } break; case VideoPlayerState.PAUSED: //Do nothing break; default: //Do nothing break; } Thread.Sleep(10); } //Clean up this.PlayerState = VideoPlayerState.STOPPED; playBin.SetState(State.Null); playBin.Dispose(); appSink.SetState(State.Null); appSink.Dispose(); playBin = null; appSink = null; }
public bool HandleURI (PlayBin2 playbin, string uri) { // Processes URIs like dvd://<device-node> and overrides // track transitioning through playbin if playback was already happening // from the device node by seeking directly to the track since the disc // is already spinning; playbin doesn't handle DVD URIs with device nodes // so we have to handle setting the device property on GstCddaBaseSrc // through the notify::source signal on playbin string new_dvd_device; if (playbin == null || String.IsNullOrEmpty (uri) || !uri.StartsWith ("dvd://")) { // Something is hosed or the URI isn't actually DVD if (Device != null) { Log.WarningFormat ("dvd: finished using device ({0})", Device); Device = null; } return false; } // 6 is the size of "dvd://" // so we skip this part to only get the device new_dvd_device = uri.Substring (6); if (Device == null) { // If we weren't already playing from a DVD, cache the // device and allow playbin to begin playing it Device = new_dvd_device; Log.DebugFormat ("dvd: storing device node for fast seeks ({0})", Device); return false; } if (new_dvd_device == Device) { Log.DebugFormat ("dvd: Already playing device ({0})", Device); return true; } // We were already playing some CD, but switched to a different device node, // so unset and re-cache the new device node and allow playbin to do its thing Log.DebugFormat ("dvd: switching devices for DVD playback (from {0}, to {1})", Device, new_dvd_device); Device = new_dvd_device; return false; }
/// <summary> /// Loads the video. Setup playbin2 and start polling thread /// </summary> /// <param name='uri'> /// video URI. /// </param> public void LoadVideo(string uri){ if (gstThread != null) { isrunning = false; gstThread.Join(); gstThread = new Thread(new ThreadStart(KeepPolling)); } if(playBin != null){ playerState = VideoPlayerState.STOPPED; Console.WriteLine("STOPPED"); //Dispose playbin2 and appsink playBin.SetState(State.Null); playBin.Dispose(); appSink.SetState(State.Null); appSink.Dispose(); //Create playbin2 and appsink playBin = new PlayBin2(); appSink = ElementFactory.Make("appsink", "sink") as AppSink; //appSink.Caps = new Caps("video/x-raw-yuv", new object[]{}); appSink.Caps = new Caps("video/x-raw-rgb", new object[] { "bpp", 24 }); appSink.Drop = true; appSink.MaxBuffers = 1; playBin.VideoSink = appSink; }else{ //Create playbin2 and appsink playBin = new PlayBin2(); appSink = ElementFactory.Make("appsink", "sink") as AppSink; //appSink.Caps = new Caps("video/x-raw-yuv", new object[]{}); appSink.Caps = new Caps("video/x-raw-rgb", new object[] { "bpp", 24 }); appSink.Drop = true; appSink.MaxBuffers = 1; playBin.VideoSink = appSink; } //init variables texturesOK = false; width = 0; height = 0; //Set file uri string validUri = uri; if (!validUri.StartsWith("file://")) { validUri = "file://" + uri; } playBin.Uri = validUri; StateChangeReturn sr = playBin.SetState(State.Playing); Console.WriteLine(sr.ToString()); playerState = VideoPlayerState.LOADING; Console.WriteLine("LOADING:" + validUri); if (gstThread == null) { gstThread = new Thread(new ThreadStart(KeepPolling)); } //Start polling thread...future thought, using async queue? isrunning = true; gstThread.Start(); return; }
public PlayerEngine () { Log.InformationFormat ("GStreamer# {0} Initializing; {1}.{2}", typeof (Gst.Version).Assembly.GetName ().Version, Gst.Version.Description, Gst.Version.Nano); // Setup the gst plugins/registry paths if running Windows if (PlatformDetection.IsWindows) { var gst_paths = new string [] { Hyena.Paths.Combine (Hyena.Paths.InstalledApplicationPrefix, "gst-plugins") }; Environment.SetEnvironmentVariable ("GST_PLUGIN_PATH", String.Join (";", gst_paths)); Environment.SetEnvironmentVariable ("GST_PLUGIN_SYSTEM_PATH", ""); Environment.SetEnvironmentVariable ("GST_DEBUG", "1"); string registry = Hyena.Paths.Combine (Hyena.Paths.ApplicationData, "registry.bin"); if (!System.IO.File.Exists (registry)) { System.IO.File.Create (registry).Close (); } Environment.SetEnvironmentVariable ("GST_REGISTRY", registry); //System.Environment.SetEnvironmentVariable ("GST_REGISTRY_FORK", "no"); Log.DebugFormat ("GST_PLUGIN_PATH = {0}", Environment.GetEnvironmentVariable ("GST_PLUGIN_PATH")); } Gst.Application.Init (); playbin = new PlayBin2 (); next_track_set = new ManualResetEvent (false); audio_sink = new AudioSinkBin ("audiobin"); playbin["audio-sink"] = audio_sink; if (audio_sink.VolumeNeedsSaving) { // Remember the volume from last time Volume = (ushort)PlayerEngineService.VolumeSchema.Get (); } Pad teepad = audio_sink.RequestTeePad (); visualization = new Visualization (audio_sink, teepad); playbin.AddNotification ("volume", OnVolumeChanged); playbin.Bus.AddWatch (OnBusMessage); playbin.AboutToFinish += OnAboutToFinish; cdda_manager = new CddaManager (playbin); dvd_manager = new DvdManager (playbin); // FIXME: Disable video stuff until GLib# 3 is used instead of the sopy bundled in GStreamerSharp //video_manager = new VideoManager (playbin); //video_manager.PrepareWindow += OnVideoPrepareWindow; //video_manager.Initialize (); dvd_manager.FindNavigation (playbin); OnStateChanged (PlayerState.Ready); }
public void HandleCommandsChanged (PlayBin2 playbin) { InDvdMenu = false; // Get available command to know if player is in menu Gst.Query query = NavigationQuery.NewCommands (); NavigationCommand[] cmds; if (Navigation == null) { FindNavigation (playbin); } if (!(((Element)Navigation).Query (query) && NavigationQuery.ParseCommands (query, out cmds))) { return; } foreach (NavigationCommand cmd in cmds) { switch (cmd) { case NavigationCommand.Activate: case NavigationCommand.Left: case NavigationCommand.Right: case NavigationCommand.Up: case NavigationCommand.Down: InDvdMenu = true; break; default: break; } } }