loupiottes/DMX-2.0/SequenceurSon.cs
arnaud.houdelette d37da1acaa Premiers jets
2025-06-17 16:22:05 +02:00

463 lines
10 KiB
C#

/*
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 <http://www.gnu.org/licenses/>.
*/
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<string> files = new List<string>();
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<string> 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(
@"(?<file>\d+)?(g(?<goto>[\d\.:]+))?(v(?<volume>\d+)(,(?<fade>\d+))?)?(?<play>(ps|p|s))?(?<repeat>(r))?",
System.Text.RegularExpressions.RegexOptions.Compiled);
static System.Text.RegularExpressions.Regex regexCommand2 = new System.Text.RegularExpressions.Regex(
@"^(?<file>\d+)(?<params>[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
}
}