/* Copyright (C) Arnaud Houdelette 2012-2014 Copyright (C) Emmanuel Langlois 2012-2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Diagnostics; using System.Xml; using System.Globalization; using System.Net; using System.Text; namespace DMX2 { public class SequenceurSon : Sequenceur, IDisposable { SeqSonUI ui=null; //Process mplayerProcess = null; List files = new List(); string curfile = string.Empty; uint volume=100; System.Net.WebClient wc =new System.Net.WebClient(); String vlcPassword = "loupiottes"; string credentials; string vlcUrl = "http://127.0.0.1:8080/requests/status.json"; TimeSpan fading=TimeSpan.Zero; TimeSpan fadeLen; int fadeVStart; int fadeVEnd; TimeSpan duration = TimeSpan.Zero; TimeSpan position = TimeSpan.Zero; bool repeat = false; actionEventTargetEx volumeEventTarget=null; public ReadOnlyCollection Files { get { return files.AsReadOnly(); } } public string CurFile { get{return curfile; } } public int Index { get { return files.IndexOf (curfile); } set { repeat = false; if(value>=0 && value< files.Count) lock(this) LoadFile(value); } } bool Paused{ get; set;} bool CheckVLC(){ return true; } void SendCommand(string command, string input) { string url; if (input != null) { string encodedInput = Uri.EscapeDataString(input); url = $"{vlcUrl}?command={command}&input={encodedInput}"; } else url = $"{vlcUrl}?command={command}"; try { string response = wc.DownloadString(url); Console.WriteLine("Réponse VLC : " + response); return; } catch (WebException e) { Console.WriteLine("Erreur lors de l'ajout du fichier : " + e.Message); return; } } public int AddFile (int pos, string file) { lock (this) { if(files.Contains(file)) return -1; files.Insert (pos, file); CommandAdd(pos); return pos; } } public uint Volume { get{ return volume;} set { volume=value; uint val = volume * 255 / 100; //if (mplayerProcess != null && !mplayerProcess.HasExited) //{ // if (!Paused) // mplayerProcess.StandardInput.WriteLine("volume {0} 1", volume); //} SendCommand($"volume&val={val}",null); volumeEventTarget.FeedBack (); } } public TimeSpan PlayTime { get{ return position; } set{ if (CheckVLC ()) { } } } public TimeSpan Duration { get { return duration; } } public void DelFile (int pos) { lock (this) { files.RemoveAt (pos); CommandRemove(pos); } } void LoadFile (int pos) { //Console.WriteLine("LoadFile"); curfile = files[pos]; Stop(); SendCommand("pl_empty", curfile); SendCommand("in_play", curfile); Paused = true; } public void Play () { if (curfile==null || !Paused) return; if (!CheckVLC ()) return; SendCommand("pl_play", null); Paused = false; } public void Pause () { if (curfile==null || Paused) return; if (!CheckVLC ()) return; SendCommand("pl_pause", null); Paused = true; } public void Stop () { CheckVLC (); SendCommand("pl_stop", null); } public SequenceurSon () { credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(":" + vlcPassword)); wc.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; volumeEventTarget = new actionEventTargetEx ( delegate(EventData data) { Volume = (uint)(100 * data.value / 255); return true; }, delegate{ return (int)(Volume * 255 /100); }, true ); } #region implemented abstract members of DMX2.Sequenceur public override SequenceurUI GetUI () { if (ui == null) { ui = new SeqSonUI (this); ui.Destroyed += UiDestroyed; } return ui; } void UiDestroyed (object sender, EventArgs e) { ui=null; } public override int ValeurCircuit (Circuit c) { return 0; } public string State { get { return string.Empty; } } void UpdateState () { } public override void Tick (TimeSpan time) { if (fading != TimeSpan.Zero) { fading-=time; if(fading<=TimeSpan.Zero){ Volume = (uint)fadeVEnd; fading=TimeSpan.Zero; } else{ Volume = (uint)( fadeVEnd + (fadeVStart-fadeVEnd) * fading.TotalMilliseconds / fadeLen.TotalMilliseconds); } } if (repeat) { } } public override void Save (System.Xml.XmlElement parent) { System.Xml.XmlElement el = parent.OwnerDocument.CreateElement ("SequenceurSon"); System.Xml.XmlElement xmlEl; parent.AppendChild (el); el.SetAttribute ("id", ID.ToString ()); el.SetAttribute ("name", Name); foreach (string file in files) { el.AppendChild(xmlEl = parent.OwnerDocument.CreateElement ("File")); xmlEl.SetAttribute("path",file); } } public static new SequenceurSon Load (Conduite conduite, System.Xml.XmlElement el) { SequenceurSon seq = new SequenceurSon(); seq.LoadSeq(conduite,el); return seq; } void LoadSeq (Conduite conduite, System.Xml.XmlElement el) { ID = int.Parse (el.GetAttribute ("id")); Name = el.GetAttribute ("name"); foreach (var xf in el.GetElementsByTagName("File")) { System.Xml.XmlElement xfil = xf as System.Xml.XmlElement; string file = xfil.GetAttribute ("path"); files.Add(file); } } static System.Text.RegularExpressions.Regex regexCommand1 = new System.Text.RegularExpressions.Regex( @"(?\d+)?(g(?[\d\.:]+))?(v(?\d+)(,(?\d+))?)?(?(ps|p|s))?(?(r))?", System.Text.RegularExpressions.RegexOptions.Compiled); static System.Text.RegularExpressions.Regex regexCommand2 = new System.Text.RegularExpressions.Regex( @"^(?\d+)(?[gvpsr](.+)?)?", System.Text.RegularExpressions.RegexOptions.Compiled); public override void Command (string command) { //Console.WriteLine("Command"); lock (this) { var cmd = regexCommand1.Match (command); if (cmd.Success) { if (cmd.Groups ["file"].Success) { int filen = int.Parse (cmd.Groups ["file"].Value) - 1; if (filen >= files.Count) return; Index = filen; if (ui != null) ui.updateflag = true; } if (cmd.Groups ["goto"].Success) { string[] formats = new string[]{ @"m\:s\.f", @"m\:s", @"h\:m\:s",@"h\:m\:s\.f" }; TimeSpan ts; if(TimeSpan.TryParseExact( cmd.Groups ["goto"].Value,formats,null,out ts)) { PlayTime = ts; } } if (cmd.Groups ["volume"].Success) { uint vol = uint.Parse (cmd.Groups ["volume"].Value); if(vol>100) vol=100; if(cmd.Groups ["fade"].Success) { fadeLen = fading = TimeSpan.FromMilliseconds (100*int.Parse (cmd.Groups ["fade"].Value)); fadeVStart = (int)volume; fadeVEnd = (int)vol; } else{ fading = TimeSpan.Zero; Volume = vol; if (ui != null) ui.updateflag = true; } } if (cmd.Groups ["play"].Success) { switch(cmd.Groups ["play"].Value) { case "p": Play(); break; case "ps": Pause(); break; case "s": Stop(); break; } } if (cmd.Groups ["repeat"].Success) { repeat = true; } } } } void CommandAdd (int index) { lock (Conduite.Courante.SequenceurMaitre) { string[] commands = Conduite.Courante.SequenceurMaitre.GetCommands (this); for (int i = 0; i < commands.Length; i++) { var cmd = regexCommand2.Match(commands[i]); if(cmd.Success){ int ef = int.Parse(cmd.Groups["file"].Value); if (ef-1>index) { ef++; commands[i] = ef.ToString() + cmd.Groups["params"].Value; } } } Conduite.Courante.SequenceurMaitre.SetCommands(this,commands); } } void CommandRemove (int index) { lock (Conduite.Courante.SequenceurMaitre) { string[] commands = Conduite.Courante.SequenceurMaitre.GetCommands (this); for (int i = 0; i < commands.Length; i++) { var cmd = regexCommand2.Match(commands[i]); if(cmd.Success){ int ef = int.Parse(cmd.Groups["file"].Value); if (ef-1 == index) commands[i] = string.Empty; else if (ef-1>index) { ef--; commands[i] = ef.ToString() + cmd.Groups["params"].Value; } } } Conduite.Courante.SequenceurMaitre.SetCommands(this,commands); } } void CommandSwap (int index) { lock (Conduite.Courante.SequenceurMaitre) { string[] commands = Conduite.Courante.SequenceurMaitre.GetCommands (this); // numeros a swapper int a = index+1; int b = index+2; for (int i = 0; i < commands.Length; i++) { var cmd = regexCommand2.Match(commands[i]); if(cmd.Success){ int ef = int.Parse(cmd.Groups["file"].Value); if (ef == a) commands[i] = b.ToString() + cmd.Groups["params"].Value; if (ef == b) commands[i] = a.ToString() + cmd.Groups["params"].Value; } } Conduite.Courante.SequenceurMaitre.SetCommands(this,commands); } } #endregion #region IDisposable implementation void IDisposable.Dispose () { } #endregion } }