Stream auf Linux-Server via udrec & mono

Digital Recording
Darth Valium
Neugieriger
Neugieriger
Beiträge: 19
Registriert: Sonntag 6. Juni 2004, 19:14

Stream auf Linux-Server via udrec & mono

Beitrag von Darth Valium »

hallo,

ich habe kuerzlich mein streaming system auf meinen linux-server geschmissen, zumal das ding weniger strom frisst und mich im alltagsgeschehen nicht allzu sehr nervt, wenn es seine ressourcen zum encoden/muxen/dvds "kompilieren" braucht.

gestreamed wird von einer dbox 2xi avia600 nokia mit 1.5. image und schuss vom 17.05..

streaming sever ist ein compaq proliant 5000, 4xppro 200mhz, 348mb ram, os istr debian woody mit ein paar sarge-brocken und custom-packages.

eingesetzte software ist mono 0.29 sowie die aktuelle udrec in kombination mit einem dirty-perl-hack und einer crontab-sicherung(rgl.maessige pruefung ob script noch laeuft).

grundsaetzlich habe ich das problem, daas mono & udrec gelegentlich "segmentation faults" produzieren, was das ganze script toeten(hierzu ist die crontab sicherung wichtig. aufgefallen ist mir hierbei, dass udrec, wenn im "-ss"-modus konstant ohne probs laeuft, sobald erfolgreiche EINE Aufnahme aufgenommen wurde (egal ob nur 1 minute). zudem scheint mir die "-xmlf" option der hauptgrund fuer die seg faults zu sein, zumindest hatte ich keine ohne die option(zwei stunden lang gestestet, udrec gestartet->ca 5 minuten gestreamed->udrec beendet und wieder von vorne). anonsten produzieren mono&udrec gelegentlich "unhandled exceptions", welche allerdings das script nicht toeten, und nur zu einem restart der ganzen geschichte fuehren.

um allerdings ein paar schweinereien direkt nach der aufnahme zu veranstalten, muss man auf die "-sso" variante zurueckgreifen.

so, hier meine probleme:

1: die seg faults: kann ich zwar abfangen, aber crontab ist nicht ideal, schliesslich soll der server 24/7 laufen, ohne 5 minuetige unterbrechungen. und einen ganzen proz nur zur absicherung dass der ss laeuft ist mir auch zu bunt. hatte jemand schon erfahrungen damit und konnte das eleganter beheben?
2: ab und an nimmt udrec nichts auf, sprich er erstellt die logdatei & das xml-file und danach nichts mehr(beendet sich, dies allerdings immer gleich nach aufnahmestart). das habe ich durch mein script abgefangen, sprich der server ist nicht mal eine sekunde nach unerfolgreicher aufnahme wieder im aufnahmemodus.
ABER: die dumme dbox interessiert das nicht. auch wenn der server kurz danach wieder "da" ist, und die dbox sowohl den timer noch gesetzt hat als auch im aufnahmemodus ist (siehe roter "o" am tv), kommen keine daten mehr an. loesche ich hingegen im webinterface den timer und setzte ihn darauf gleich wieder neu, laeuft die aufnahme (es sei denn 2. poassiert wieder). gibt es hier die moeglichkeit, dass zu automatisieren, bzw. die box bei ausfallendem streaming-server dazu zu zwingen, den timer automatisch neu zu setzen(um so die aufnahme nochmal zu starten)?-

eventuell kann mir ja einer von euch helfen, bevor ich in meine taste beisse :-)

geplant habe ich langfristig mir mittels den mguides von premiere, ein bisschen perl und cgi mir ein webinterface auf basis der monatsdaten zu basteln, welche udrec-serverseitig aufnahmen triggern laesst, allerdings liegt das ertmal auf eis, bis ich das obengenannte geloest habe. ein script, dass mir die mguides in ein passendes format parsed habe ich fertig, muss dieses nur entsprechend aendern (brauchte es, um die mguides passgerecht fuer meine filmdatenbank unter access zu konvertieren, sprich tabellarisch und ohne renundanzen; beim konvertieren spaetere mguides werden die eintraege geprueft, und nur noch nicht vorhandene filme werden dem export-file uebergeben).

ahja, hier noch die scripte (sind wirklich sehr dirty hacks, und meine erste perl-arbeit seit 5 jahren, also verzeiht ueble schnitzer!!):

aufname.pl (schmeisst udrec an, prueft nach ende von udrec die ausgabe, und benennt, falls erfolgreich aufgenommen wurde, die dateien anhand der infos aus der xml-datei die files um).
die pruefung auf segmenfaults bzw. exceptions bringen nichts, da ich diese nicht in mein array bekomme.

Code: Alles auswählen

#!/usr/bin/perl

$LOG_FILE="/var/log/aufnahme.log";

&aufnahme();

sub aufnahme
  {
    open(LOGGER,">>$LOG_FILE");
    # udrec toeten
    print `/root/killudrec.sh`;
    print LOGGER ("Starte Aufnahme-Server!\n");
    @elemarray="";
    $xml="";
    $movies="";
    @aufnahme=`mono /usr/bin/udrec.exe -sso -o /media/video/Premiere/ -es -idd -vsplit 2 -log -mplex -xmlf`;
    foreach (@aufnahme)
      {
	chomp;
	if($_=~/.xml/g) { $xml=$_; }
	elsif ($_=~/.mpv/g) { $movies=$_; }
	elsif ($_=~/Segmentation/g) { print LOGGER ("Segmentation fault: $_\n"); close (LOGGER); &aufnahme(); }
	elsif ($_=~/Unhandled Exception/g) { print LOGGER ("Ausnahmefehler: $_\n"); close (LOGGER); &aufnahme(); }
	else { print LOGGER ("Nicht erkannt: $_\n"); }
      }
    if(($xml ne "")&&($movies ne "")) { &umbenennen(); }
    else { print LOGGER ("Keine Files uebertragen !\n"); close (LOGGER); aufnahme(); }
  }
sub umbenennen
  {
    print LOGGER ("Oeffne $xml....\n");

    open (IN_PUT, "$xml");
    while (<IN_PUT>)
      {
	chomp;
	if($_=~/<epgtitle>/g) 
	  {
	    $_=~s/\s*<epgtitle>//;
	    $_=~s/<\/epgtitle>//;
	    print LOGGER ("Filmtitel gefunden: $_\n");
	    $titel=$_;
	    last;
	  }
      }
    close (IN_PUT);
    
    @movie_arr=split (/\s/,$movies);
    $xml_kon=$xml;
    $xml_kon=~s/.xml//;
    $number=$xml;
    $number=~s/[a-z]*//g;
    $number=~s/[A-Z]*//g;
    $number=~s/\///g;
    $number=~s/\.//g;
    $path=$xml;
    $path=~s/\d.*//;
    $log=$xml;
    $log=~s/.xml/.log/;
    $log_neu=$log;
    $log_neu=~s/$xml_kon/$titel/;
    $log_neu=$path.$log_neu;
    
    print LOGGER ("Strings:\n");
    print LOGGER ("Number: $number\n");
    print LOGGER ("Path:   $path\n");
    print LOGGER ("\nUdrec-LOG:\n");

    open (TMP_LOG,"$log");
    while(<TMP_LOG>){ chomp; print LOGGER ("\t$_\n"); }
    close (TMP_LOG);

    if (-e $log_neu) { $log_neu=$log_neu.".".$number; }
	
    if (-e $log)
      {
	print `mv "$log" "$log_neu"`;
	print LOGGER ("Logfile: $log\n");
	print LOGGER ("nach:    $log_neu umbenannt!\n");
     }
    
    foreach $elem(@movie_arr)
      {
	if($elem=~/mpv/g)  
	  { 
	    if (-e $elem)
	      {
		$video_neu=$elem;
		$video_neu=~s/$xml_kon/$titel/;
		$video_neu=$path.$video_neu;
		if (-e $video_neu) { $video_neu=$video_neu.".".$number; }
		print `mv "$elem" "$video_neu"`;
		print LOGGER ("Videospur:\n");
		print LOGGER ("$elem in\n");
		print LOGGER ("$video_neu umbenannt\n");
		$elem_idd=$elem;
		$elem_idd=~s/.mpv/.idd/;
		if(-e $elem_idd) 
		  { 
		    $elem_idd_new=$elem_idd;
		    $elem_idd_new=~s/$xml_kon/$titel/;
		    $elem_idd_new=$path.$elem_idd_new;
		    if (-e $elem_idd_new) { $elem_idd_new=$elem_idd_new.".".$number; }
		    print `mv "$elem_idd" "$elem_idd_new"`;
		  }
	      }
	    else { print LOGGER ("Keine Videospur an $elem!!!\n"); }
	  }
	elsif($elem=~/mp2/g) 
	  { 
	    if (-e $elem)
	      {
		$audio_neu=$elem;
		$audio_neu=~s/$xml_kon/$titel/;
		$audio_neu=$path.$audio_neu;
		if (-e $audio_neu) { $audio_neu=$audio_neu.".".$number; }
		print `mv "$elem" "$audio_neu"`;
		print LOGGER ("Audiospur:\n");
		print LOGGER ("$elem in\n");
		print LOGGER ("$audio_neu umbenannt\n");
		$elem_idd=$elem.".idd";
		
		if(-e $elem_idd) 
		  { 
		    $elem_idd_new=$elem_idd;
		    $elem_idd_new=~s/$xml_kon/$titel/;
		    $elem_idd_new=$path.$elem_idd_new;
		    if (-e $elem_idd_new) { $elem_idd_new=$elem_idd_new.".".$number; }
		    print `mv "$elem_idd" "$elem_idd_new"`;
		  }
	      }
	    else { print LOGGER ("Keine Audiospur an $elem!!!\n"); }
	  }
	elsif($elem=~/ac3/g) 
	  { 
	    if (-e $elem)
	      {
		$audio_neu=$elem;
		$audio_neu=~s/$xml_kon/$titel/;
		$audio_neu=$path.$audio_neu;
		if (-e $audio_neu) { $audio_neu=$audio_neu.".".$number; }
		print `mv "$elem" "$audio_neu"`;
		print LOGGER ("AC3-Spur:\n");
		print LOGGER ("$elem in\n");
		print LOGGER ("$audio_neu umbenannt\n");
		$elem_idd=$elem.".idd";
		
		    if(-e $elem_idd) 
		      { 
			$elem_idd_new=$elem_idd;
			$elem_idd_new=~s/$xml_kon/$titel/;
			$elem_idd_new=$path.$elem_idd_new;
			if (-e $elem_idd_new) { $elem_idd_new=$elem_idd_new.".".$number; }
			print `mv "$elem_idd" "$elem_idd_new"`;
		      }
	      }
	    else { print LOGGER ("Keine AC3-Spur an $elem!!!\n"); }
	  }
      }
    print LOGGER ("\nStarte Udrec neu\n");
    close (LOGGER);
    &aufnahme();
  }
killudrec.sh (ist ein kleines shell script, um den tod von mono /udrec vor neubgeinn sicherzustellen):

Code: Alles auswählen

#!/bin/bash

SS_PID=`pidof mono`
if [ ! -z "$SS_PID" ]; then
     kill -9 $SS_PID > /dev/null 2>&1
                #
                # to be sure ...
            #
     sleep 1
     PID=`fuser -n tcp 4000 | grep "4000/tcp" | awk '{print $2}'`
       if [ ! -z "$PID" ]; then
               kill -9 $PID
       fi
fi
und fuer dies interessiert, der mguide-access-koverter:

Code: Alles auswählen

#!/usr/bin/perl
# Projekt:	Script zur Konvertierung von
# 		Premiere Monats - Txts in Excel-Kompatibles Format
# Beispiel:	./konvert.pl ./mguide_d_s_05_04.txt
# Needs:	mguide*.txt
# Makes:	MM_YY_Premiere_Excel.txt
# Version: 0.01
# Juni 2004
# Author:  ICH
# 

print (`clear`);

%filmhash;
$i=0;
$k=0;
$zaehler=0;


if ($ARGV[0] eq "")
{
	&error_msg();
}
elsif (-e "$ARGV[0]")
{
	$mguide=$ARGV[0];
}
else
{
	&error_msg();
}

$mguidenew=$mguide;
$mguidenew=~s/mguide_d_s_//;
$mguidenew=~s/.txt/_Premiere_Excel.txt/;

&auslesen($mguide);
# &main_base_pruefen();
# &file_schreiben();

sub auslesen
{
	my $tmp=$_[0];
	my @array="";
	my $string;
	open (REF_IN,"$tmp")||print("Dateifehler in $tmp.\n");
	print "Lese Ursprungsdatei: $tmp aus!\n";
	$unterbrecher=0;
	while (<REF_IN>)
	{
		chomp;
                if ($_=~/^[A-Z][A-Z]/||$_=~/^13TH/)
                {
			# Zwei Grossbuchstaben ist Kanal
                        # print "Kanal gefunden!\n";
                        next;
                }
		elsif ($_=~/^Bild- und/) 
		{ 
			# Bild- und Tonregie raus
			# print "Bild- und Tonregie entfernt!\n";
			next; 
		}
		elsif ($_ eq "\r") 
		{
			# Leerzeile entdeckt = Neuer Eintrag
			# print "Leerzeile entdeckt\n";
			# print "$string";
			$string=~s/""/"/g;
			@array= split /\t/,$string;
			$i++;
		 	$j=0;
			$string="";	
			foreach $elem(@array)
			{
				if ($j==0)
				{
					if ($filmhash{$elem} ne "") { $k++;last; }
					else
					{	
						$filmhash{$elem}="";
						$filmkey=$elem;	
					}				
				}
				elsif ($j==8) { $string=~s/\t//g; $filmhash{$filmkey}= $filmhash{$filmkey}.$elem; }
				else { $string=~s/\t//g; $filmhash{$filmkey}=$filmhash{$filmkey}.$elem."\t"; }
				$j++;
			}
			# print "Folgender Eintrag vorgenommen:\n";
			# foreach $key(keys %filmhash) { print "$key\t$filmhash{$key}\n"; }
			next; 
		} 
		else 
		{
			# Film Informationen
			# DOS Zeilenumbruch entfernen
			$_=~s/\sStunden\x0D/\x0D/;
			$_=~s/\x0D//g;
			# Titel, Epsiode, etc entfernen
			$_=~s/Titel:\s+//;
			$_=~s/Episode:\s+//;
			$_=~s/-*\s+Genre:\s+/\t/;
			$_=~s/-*\s+L.nge:\s+/\t/;
			$_=~s/Produktionsland:\s+//;
			$_=~s/-*\s+Produktionsjahr:\s+/\t/;
			$_=~s/-*\s+Regie:\s+/\t/;
			$_=~s/Darsteller:\s+//;

			$string=$string."$_\t";
			# print ("$string\n");
		}
	# Auskommentieren um Suchzeit zu verkuerzen - TESTZWECKE
	# $unterbrecher++;
	# if($unterbrecher==100) { last; }
	}
	close (REF_IN);
	&main_base_pruefen();
}

sub main_base_pruefen
{
	$haupt="/home/aleman/Premiere_Perl_Konvertierung/gesamt.txt";

	if (-e $haupt)
        {
		print "\Gesamtuebersicht existiert. Pruefe doppelte Eintraege.\n";
		&main_base_auslesen(); 
                open(BASE_OUT,">>$haupt")||die("Cannot create/open file.\n");
		foreach $key (keys (%filmhash)) { print BASE_OUT ("$key\n"); }
		close (BASE_OUT);
		&file_schreiben();
        }
        else
        {
                open(BASE_OUT,">$haupt")||die("Cannot create/open file.\n");
		print "Erstelle Gesamtuebersicht neu.\n";	
		foreach $key (keys (%filmhash)) { print BASE_OUT ("$key\n"); }
		close (BASE_OUT);
		&file_schreiben();
        }
}

sub main_base_auslesen
{
	open(BASE_IN,"$haupt")||die("Cannot create/open file.\n");
	while(<BASE_IN>)
	{
		chomp;
		push(@liste,$_);
	}
	close (BASE_IN);
	foreach $eintrag(@liste)
	{
		if($filmhash{$eintrag} ne "") { delete $filmhash{$eintrag}; $zaehler++;}
	}
}

sub file_schreiben 
{
        if (-e $mguidenew)
        {
                open(REF_OUT,">/home/aleman/Premiere_Perl_Konvertierung/$mguidenew")||die("Cannot create/open file.\n");
                print "Output-File $mguidenew existiert....Ueberschreibe!\n";
        }
        else
        {
                open(REF_OUT,">>/home/aleman/Premiere_Perl_Konvertierung/$mguidenew")||die("Cannot create/open file.\n");
                print "Output-File $mguidenew existiert neu angelegt!\n";
        }

        foreach $key (keys (%filmhash))
        {
                print REF_OUT "$key\t$filmhash{$key}\n";
        }
        $neu=$i-$k;
        print "\n$i Filme gesamt gefunden, davon $k Mehrfachnennung.\n";
	print "Von $neu Eindeutigen sind $zaehler schon vorhanden.\n\n";
	close(REF_OUT);
}

sub error_msg {
print "\n+---------------------------------------+\n";
print "| Usage: kovert.pl mguige_d_s_MM-YY.txt |\n";
print "+---------------------------------------+\n\n";
}
gagga
Senior Member
Beiträge: 782
Registriert: Dienstag 25. Februar 2003, 21:35

Beitrag von gagga »

Zu 1.: Probier mal eine neuere mono Version. Seitdem ich mono beta 2 benutze habe ich keinerlei segfaults mehr.
Darth Valium
Neugieriger
Neugieriger
Beiträge: 19
Registriert: Sonntag 6. Juni 2004, 19:14

Beitrag von Darth Valium »

jo, guter gedanke!

als ich mir mono besorgte, gabs fuer die neueste version noch keine apt-get quellen, und faulheit siegte :-).

hattest du auch dieses problem?
Zuletzt geändert von Darth Valium am Montag 7. Juni 2004, 00:01, insgesamt 1-mal geändert.
gagga
Senior Member
Beiträge: 782
Registriert: Dienstag 25. Februar 2003, 21:35

Beitrag von gagga »

Ja. Allerdings auf Fedora Core 1.
Darth Valium
Neugieriger
Neugieriger
Beiträge: 19
Registriert: Sonntag 6. Juni 2004, 19:14

Beitrag von Darth Valium »

dann erhoff ich mir da einiges. gerade die "alten" mono debs deinstalliert und lass die sourcen mal durch mein isdn troeppeln.

benutzt du die neuen udrecs als substitut innerhalb der udrec-suite oder faehrst du eine selbstgestrickte loesung? und falls ja, timest du deine aufnahmen ueber die box(an und fuer sich okay; wenn da nicht das kleine zeitfenster waere) oder triggerst du die aufnahmen vom server aus?

---
edit: sehe gerade die number of the beast, glueckwunsch zum post 666
:evil: :evil: :evil: :evil: :evil: :evil:
gagga
Senior Member
Beiträge: 782
Registriert: Dienstag 25. Februar 2003, 21:35

Beitrag von gagga »

Darth Valium hat geschrieben: benutzt du die neuen udrecs als substitut innerhalb der udrec-suite oder faehrst du eine selbstgestrickte loesung? und falls ja, timest du deine aufnahmen ueber die box(an und fuer sich okay; wenn da nicht das kleine zeitfenster waere) oder triggerst du die aufnahmen vom server aus?
Ich benutze udrec 0.12e und benutze ausschließlich die Timer der dbox.
Darth Valium
Neugieriger
Neugieriger
Beiträge: 19
Registriert: Sonntag 6. Juni 2004, 19:14

Beitrag von Darth Valium »

in die richtung gehen gerade meine ueberlegungen.
so wie ich das sehe, ist dem timer der dbox im prinzip keine"4-tage" grenze gesetzt, vorausgesetzt man verzichtet auf die epg-timer.

die noetigen daten kann man ja direkt aus der "dboxip/fb/timer.dbox2?action=new-form" gewinnen, und eben an diese adresse ja auch script gesteuert timer uebergeben, im idealfall die fuer einen ganzen monat. das spart mir dann die quaelerei mit den ganzen pids.

oder weiss jemand in diesem bezug etwas, was den plan sich in luft aufloesen laesst?

edit:
super ! die mono beta 2 hats gefixed, die streams werden aufgenommen, hatte in den letzten zwei stunden weder seg faults noch uexceptions.

danke!
tonsel
Erleuchteter
Erleuchteter
Beiträge: 536
Registriert: Freitag 21. September 2001, 00:00

Beitrag von tonsel »

Ich habe mono seit Version 0.28 immer selbst kompiliert und hatte noch nie einen segmentation fault. Auch sonst läuft mono bei mir absolut stabil.

tonsel