Encoderlösung für Livestreams



  • Hallo,

    ich habe mehrere IP-Kameras (Axis und Enso), welche im MJPEG-Format ihre Livestreams zur Verfügung stellen. Das ganze sieht bei der Axis-Kamera z. B. so aus "http://192.168.6.90/axis-cgi/mjpg/video.cgi".
    Ich möchte nun diese Signale mit einem Encoder abgreifen, z. B. den Helix DNA Realproducer oder über MPEG4IP. Das Problem besteht nun in der Übergabe des Livestreams an die Encoder. Diese können nur über eine Capturekarte oder einen Dateinamen auf die Quellen zugreifen. Da ich weder das eine noch das andere habe, komme ich an der Stelle nicht weiter.

    Nun zu meinen Ideen - ich kann über Sockets auf die Quellen zugreifen und kann die gelesenen Daten auf die Platte schreiben als z. B.
    out.mjpeg. Diese kann ich mir dann z. B. mit dem MPlayer ansehen.

    Wie kann ich aber diese Daten an einen Encoder weitergeben? Hat jemand dazu eine Idee oder gibt es schon Lösungen dazu? Ich habe mehrere Tage gegoogelt und gesucht - aber ich komme zu keinem Ergebnis.

    Es müsste doch irgendwie möglich sein dieses Problem zu lösen.

    Ich habe mal den Quelltext eines Beispiels, welches ich im Netz gefunden habe, angehängt. Damit kann ich eine kleine Datei anlegen und diese dann lesen. Das Problem ist jedoch, das die Datei immer größer wird - ich möchte aber keine Aufzeichnungen.

    Ich würde mich freuen wenn mir hier weitergeholfen werden kann. Ich habe auch noch nicht so tiefe Erfahrungen in der Programnmierung und arbeite auch noch nicht allzu lange mit Linux. Benutzen tue ich Debian in der aktuellen Version ohne X. Aber ich tue mein bestes.

    mfg

    Reiner

    Hier der Quelltext:

    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    
    /*  User defined parameters - EDIT HERE */ #define IPADDR "127.0.0.1" /* IP address of motion server, 127.0.0.1 = localhost */
    #define PORTNUMBER 80      /* Port number of camera */
    #define URLPATH "/cam1/jpeg.jpg" /* path following ipadr and portno. */ #define USERPASS "" /* "username:password"  */
    /*  End of user defined parameters */
    
    #define REQUEST_AUTH "GET %s HTTP/1.0\r\nAuthorization: Basic %s\r\n\r\n"
    #define REQUEST "GET %s HTTP/1.0\r\n\r\n"
    
    void base64_encode(const char *s, char *store, int length) {
    	/* Conversion table.  */
    	static char tbl[64] = {
    		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
    		'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
    		'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
    		'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
    		'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
    		'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
    		'w', 'x', 'y', 'z', '0', '1', '2', '3',
    		'4', '5', '6', '7', '8', '9', '+', '/'
    	};
    
    	int i;
    	unsigned char *p = (unsigned char *) store;
    
    	/* Transform the 3x8 bits to 4x6 bits, as required by base64.  */
    	for (i = 0; i < length; i += 3) {
    		*p++ = tbl[s[0] >> 2];
    		*p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)];
    		*p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)];
    		*p++ = tbl[s[2] & 0x3f];
    		s += 3;
    	}
    
    	/* Pad the result if necessary...  */
    	if (i == length + 1)
    		*(p - 1) = '=';
    	else if (i == length + 2)
    		*(p - 1) = *(p - 2) = '=';
    
    	/* ...and zero-terminate it.  */
    	*p = '\0';
    }
    
    int main()
    {
    	int sockfd;
    	int len;
    	int i;
    	struct sockaddr_in address;
    	int result;
    	char *dummy;
    	char buffer[65536];
    	char *request;
    
    /* Build request string */
    
    	if (strlen(USERPASS)) {
    		char *userpass=malloc(strlen(USERPASS)+4);
    		char *userp=malloc(strlen(USERPASS)+4);
    		memset(userpass,0,strlen(USERPASS)+4);
    		memset(userp,0,strlen(USERPASS)+4);
    		strcpy(userpass,USERPASS);
    		strcpy(userp,USERPASS);
    		base64_encode(userpass, userp, strlen(USERPASS));
    		request = (char *) malloc(strlen(REQUEST_AUTH) +
    		          strlen(URLPATH) + strlen(userp) + 1);
    		sprintf(request, REQUEST_AUTH, URLPATH, userp);
    		free(userpass);
    		free(userp);
    		printf("%s",request);
    	} else {
    		request = (char *) malloc(strlen(REQUEST) +
    		          strlen(URLPATH) + 1);
    		sprintf(request, REQUEST, URLPATH);
    	}
    
    /*  Create a socket for the client.  */
    
    	sockfd = socket(PF_INET, SOCK_STREAM, 0);
    
    /*  Name the socket, as agreed with the server.  */
    
    	address.sin_family = AF_INET;
    	address.sin_addr.s_addr = inet_addr(IPADDR);
    	address.sin_port = htons(PORTNUMBER);
    	len = sizeof(address);
    
    /*  Now connect our socket to the server's socket.  */
    
    	result = connect(sockfd, (struct sockaddr *)&address, len);
    
    	if(result == -1)
    	{
    		perror("oops: Cannot connect to socket");
    		exit(1);
    	}
    
    /*  We can now read/write via sockfd.  */
    
    /*  Send request to network camera */
    
    	send(sockfd, request, strlen(request), 0);
    
    	free(request);
    
    /*  Read 100000 bytes to get a couple of images. */
    
    	for(i=0; i<100000;)
    	{
    		dummy = buffer;
    		/* read as much as is possible for a read
    		* if less is available: don't worry, read will return
    		* what is available
    		*/
    		int n = read(sockfd, buffer, 65536);
    
    		/* read failed? */
    		if (n == -1)
    		{
    			/* read was interrupted? then just do it
    			* again
    			*/
    			if (errno == EINTR)
    				continue;
    
    			exit(1);
    		}
    		/* n=0 means socket is closed */
    		if (n == 0)
    			break;
    
    		i += n;
    
    		/* send received buffer to stdout descriptor
    		* again: as much as possible so that you have
    		* not so much buffers
    		*/
    		while(n > 0)
    		{
    			/* send some */
    			int nsend = write(1, dummy, n);
    
    			if (nsend == -1)
    			{
    				if (errno == EINTR)
    					continue;
    
    				exit(1);
    			}
    			/* strange: stdout is close?! */
    			else if (nsend == 0)
    				exit(1);
    
    			/* keep track of what was send */
    			dummy += nsend;
    			n -= nsend;
    		}
    	}
    
    	close(sockfd);
    	exit(0);
    }
    


  • mencoder kann afaik streams direkt kodieren.


Anmelden zum Antworten