]> git.zerfleddert.de Git - record-dvb/commitdiff
record a stream (for example from getstream)
authormichael <michael>
Sat, 1 Jul 2006 17:02:54 +0000 (17:02 +0000)
committermichael <michael>
Sat, 1 Jul 2006 17:02:54 +0000 (17:02 +0000)
.cvsignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
common.c [new file with mode: 0644]
common.h [new file with mode: 0644]
http.c [new file with mode: 0644]
http.h [new file with mode: 0644]
mcast.c [new file with mode: 0644]
mcast.h [new file with mode: 0644]
record-dvb.c [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..5a75ec1
--- /dev/null
@@ -0,0 +1,2 @@
+record-dvb
+*.d
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..f3306ce
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,19 @@
+CFLAGS =-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -g
+
+OBJS = record-dvb.o http.o mcast.o common.o
+
+all: record-dvb
+
+DEPEND=$(OBJS:.o=.d)
+-include $(DEPEND)
+
+record-dvb: $(OBJS)
+
+clean:
+       rm -f record-dvb $(OBJS) $(DEPEND)
+
+%.o: %.c
+       $(COMPILE.c) $(OUTPUT_OPTION) $<
+       $(COMPILE.c) -MM $< > $*.d
+
+.PHONY: all clean
diff --git a/common.c b/common.c
new file mode 100644 (file)
index 0000000..97ec807
--- /dev/null
+++ b/common.c
@@ -0,0 +1,64 @@
+#include <strings.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "common.h"
+
+struct dvb_host *parse(char *urlpart, char *defport)
+{
+       struct dvb_host *dvbhost;
+       char *pos;
+
+       if (!(dvbhost = malloc(sizeof(struct dvb_host)))) {
+               perror("malloc");
+               exit(EXIT_FAILURE);
+       }
+
+       bzero(dvbhost, sizeof(struct dvb_host));
+       
+       if (!(dvbhost->hostname = strdup(urlpart))) {
+               perror("strdup");
+               exit(EXIT_FAILURE);
+       }
+
+       /* Unneded, but better readablity: */
+       dvbhost->location = NULL;
+       dvbhost->port = NULL;
+
+       pos = dvbhost->hostname;
+
+       while(*pos != '\0' && *pos != ':' && *pos != '/')
+               pos++;
+
+       if (*pos == '/')
+               dvbhost->location = pos + 1;
+
+       if (*pos == ':')
+               dvbhost->port = pos + 1;
+
+       *pos = 0;
+
+       if (dvbhost->port) {
+               pos++;
+
+               while(*pos != '\0' && *pos != '/')
+                       pos ++;
+
+               if(*pos == '/')
+                       dvbhost->location = pos + 1;
+
+               *pos = 0;
+       }
+
+       if (!dvbhost->port)
+               dvbhost->port = strdup(defport);
+
+       if (!dvbhost->location)
+               if(!(dvbhost->location = strdup(""))) {
+                       perror("strdup");
+                       exit(EXIT_FAILURE);
+               }
+
+       return dvbhost;
+}
diff --git a/common.h b/common.h
new file mode 100644 (file)
index 0000000..5f7b1f8
--- /dev/null
+++ b/common.h
@@ -0,0 +1,7 @@
+struct dvb_host {
+       char *hostname;
+       char *port;
+       char *location;
+};
+
+struct dvb_host *parse(char *urlpart, char *defport);
diff --git a/http.c b/http.c
new file mode 100644 (file)
index 0000000..a4f4c91
--- /dev/null
+++ b/http.c
@@ -0,0 +1,86 @@
+#include <strings.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "common.h"
+#include "http.h"
+
+#define BUFFSIZE 1024
+
+int is_http(char *url)
+{
+       if (strlen(url) < 8)
+               return 0;
+
+       if (!strncasecmp("http://",url,7))
+               return 1;
+
+       return 0;
+}
+
+int open_http(char *url)
+{
+       int fd;
+       struct sockaddr_in server;
+       struct dvb_host *dvbhost;
+       struct addrinfo *s_addrinfo, addrhints;
+       char buffer[BUFFSIZE];
+       int i;
+
+       if(!is_http(url))
+               return -1;
+
+       dvbhost = parse(&(url[7]), "80");
+
+       bzero(&addrhints, sizeof(struct addrinfo));
+       addrhints.ai_family = PF_INET;
+       addrhints.ai_socktype = SOCK_STREAM;
+
+       if ((i=getaddrinfo(dvbhost->hostname, dvbhost->port, &addrhints, &s_addrinfo))) {
+               fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(i));
+               return -1;
+       }
+
+       if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+               perror("socket");
+               return -1;
+       }
+
+       bzero(&server, sizeof(struct sockaddr_in));
+       server.sin_family = AF_INET;
+       server.sin_addr.s_addr = ((struct sockaddr_in*)(s_addrinfo->ai_addr))->sin_addr.s_addr;
+       server.sin_port = ((struct sockaddr_in*)(s_addrinfo->ai_addr))->sin_port;
+
+       if (connect(fd, (struct sockaddr*) &server, sizeof(server)) < 0) {
+               perror("connect");
+               return -1;
+       }
+
+       freeaddrinfo(s_addrinfo);
+
+
+       snprintf(buffer, BUFFSIZE-1, "GET /%s HTTP/1.0\n\n",dvbhost->location);
+       buffer[BUFFSIZE-1] = 0;
+       send(fd, buffer, strlen(buffer), 0);
+       i = 0;
+       while(i < 2) {
+               if (recv(fd, buffer, 1, 0) < 1) {
+                       perror("recv");
+                       exit(EXIT_FAILURE);
+               }
+               printf("%c",buffer[0]);
+               if (buffer[0] == 0x0a)
+                       i++;
+               else
+                       if (buffer[0] != 0x0d)
+                               i = 0;
+       }
+
+       return fd;
+}
diff --git a/http.h b/http.h
new file mode 100644 (file)
index 0000000..f5f5cb1
--- /dev/null
+++ b/http.h
@@ -0,0 +1,2 @@
+int is_http(char *url);
+int open_http(char *url);
diff --git a/mcast.c b/mcast.c
new file mode 100644 (file)
index 0000000..a8be22f
--- /dev/null
+++ b/mcast.c
@@ -0,0 +1,23 @@
+#include <strings.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mcast.h"
+
+int is_mcast(char *url)
+{
+       if (strlen(url) < 7)
+               return 0;
+
+       if (!strncasecmp("udp://",url,6))
+               return 1;
+
+       return 0;
+}
+
+int open_mcast(char *url)
+{
+       fprintf(stderr,"multicast currently unimplemented!\n");
+
+       exit(EXIT_FAILURE);
+}
diff --git a/mcast.h b/mcast.h
new file mode 100644 (file)
index 0000000..e60cc90
--- /dev/null
+++ b/mcast.h
@@ -0,0 +1,2 @@
+int is_mcast(char *url);
+int open_mcast(char *url);
diff --git a/record-dvb.c b/record-dvb.c
new file mode 100644 (file)
index 0000000..aa48bb4
--- /dev/null
@@ -0,0 +1,91 @@
+#include <features.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <strings.h>
+
+#include "http.h"
+#include "mcast.h"
+
+#define CHUNKSIZE 8192
+
+void record(int(*open_fn)(char *), char *url, char *outfile, int duration)
+{
+       struct timeval start, curr;
+       int bytes, written;
+       char buffer[CHUNKSIZE];
+       int i;
+       int in, out;
+
+       if ((out = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_LARGEFILE, 00644)) < 0) {
+               perror("open");
+               exit(EXIT_FAILURE);
+       }
+
+       if ((in = (*open_fn)(url)) < 0) {
+               fprintf(stderr,"Can't open url %s!\n",url);
+               exit(EXIT_FAILURE);
+       }
+
+       printf("Recording from %s for %d seconds...\n", url, duration);
+
+       gettimeofday(&start, NULL);
+
+       do {
+               if ((bytes = recv(in, buffer, CHUNKSIZE, 0)) < 1) {
+                       perror("recv");
+                       exit(EXIT_FAILURE);
+               }
+
+               written = 0;
+               do {
+                       if ((i = write(out, buffer, bytes-written)) < 0) {
+                               perror("write");
+                               exit(EXIT_FAILURE);
+                       }
+                       written += i;
+               } while(written < bytes);
+
+               gettimeofday(&curr, NULL);
+       } while (curr.tv_sec < start.tv_sec+duration);
+
+       close(out);
+       close(in);
+       shutdown(in, SHUT_RDWR);
+}
+
+int main(int argc, char **argv)
+{
+       int duration;
+       char *url;
+       char *outfile;
+       int(*open_fn)(char *);
+
+       if (argc == 4) {
+               url = argv[1];
+               duration = atol(argv[2])*60;
+               outfile = argv[3];
+       } else {
+               fprintf(stderr,"Syntax: %s URL duration outfile\n", argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       if (is_http(url)) {
+               open_fn = &open_http;
+       } else if (is_mcast(url)) {
+               open_fn = &open_mcast;
+       } else {
+               printf("URL %s not supported!\n", url);
+               exit(EXIT_FAILURE);
+       }
+
+       record(open_fn, url, outfile, duration);
+
+       return EXIT_SUCCESS;
+}
Impressum, Datenschutz