Hi,
I'm using the plaympeg.c (modified) code of smpeg as a media player. I've got ffserver running as a streaming server. I'm a streaming an mp3 file over http. But when I run plaympeg.c, it plays the streamed file only for a second. When I run plaympeg again, it starts off from where it left and plays for 1 second.
Does anyone know why this happens an how to fix it?
I've tested it out on WMP and it plays the entire file in one go. So, i guess it's not a problem with the streaming or ffserver.conf
include
include
include
include
/* #ifdef unix */
include
include
include
include
include
include
include
define NET_SUPPORT /* General network support */
define HTTP_SUPPORT /* HTTP support */
ifdef NET_SUPPORT
include
include
include
include
endif
include "smpeg.h"
ifdef NET_SUPPORT
int tcp_open(char * address, int port)
{
struct sockaddr_in stAddr;
struct hostent * host;
int sock;
struct linger l;
memset(&stAddr,0,sizeof(stAddr));
stAddr.sin_family = AF_INET ;
stAddr.sin_port = htons(port);
if((host = gethostbyname(address)) == NULL) return(0);
stAddr.sin_addr = *((struct in_addr *) host-h_addr_list[0]) ;
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) return(0);
l.l_onoff = 1; l.l_linger = 5;
if(setsockopt(sock, SOL_SOCKET, SO_LINGER, (char*) &l, sizeof(l)) < 0) return(0);
if(connect(sock, (struct sockaddr *) &stAddr, sizeof(stAddr)) < 0) return(0);
return(sock);
}
ifdef HTTP_SUPPORT
int http_open(char * arg)
{
char * host;
int port;
char * request;
int tcp_sock;
char http_request[1024];
char c;
printf("\nin http_open passed parameter = %s\n",arg);
/* Check for URL syntax */
if(strncmp(arg, "http://", strlen("http://"))) return(0);
/* Parse URL */
port = 80;
host = arg + strlen("http://");
if((request = strchr(host, '/')) == NULL) return(0);
request++ = 0;
if(strchr(host, ':') != NULL) / port is specified */
{
port = atoi(strchr(host, ':') + 1);
*strchr(host, ':') = 0;
}
/* Open a TCP socket */
if(!(tcp_sock = tcp_open(host, port)))
{
perror("http_open");
return(0);
}
/* Send HTTP GET request */
sprintf(http_request,
"GET /%s HTTP/1.0\r\n"
"User-Agent: Mozilla/2.0 (Win95; I)\r\n"
"Pragma: no-cache\r\n"
"Host: %s\r\n"
"Accept: /\r\n"
"\r\n",
request, host);
send(tcp_sock, http_request, strlen(http_request), 0);
/* Parse server reply */
do read(tcp_sock, &c, sizeof(char)); while(c != ' ');
read(tcp_sock, http_request, 4*sizeof(char));
http_request[4] = 0;
if(strcmp(http_request, "200 "))
{
fprintf(stderr, "http_open: ");
do {
read(tcp_sock, &c, sizeof(char));
fprintf(stderr, "%c", c);
}
while(c != '\r');
fprintf(stderr, "\n");
return(0);
}
return(tcp_sock);
}
endif
endif
void update(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
{
if ( screen-flags & SDL_DOUBLEBUF ) {
SDL_Flip(screen);
}
}
/* Flag telling the UI that the movie or song should be skipped */
int done;
void next_movie(int sig)
{
done = 1;
}
int main(int argc, char *argv[])
{
int use_audio, use_video;
int fullscreen;
int scalesize;
int scale_width, scale_height;
int loop_play;
int i, pause;
int volume;
Uint32 seek;
float skip;
int bilinear_filtering;
SDL_Surface *screen;
SMPEG *mpeg;
SMPEG_Info info;
char *basefile;
SDL_version sdlver;
SMPEG_version smpegver;
int fd;
char buf[32];
int status;
printf("\nchecking command line options ");
/* Get the command line options */
use_audio = 1;
use_video = 1;
fullscreen = 0;
scalesize = 1;
scale_width = 0;
scale_height = 0;
loop_play = 0;
volume = 100;
seek = 0;
skip = 0;
bilinear_filtering = 0;
fd = 0;
for ( i=1; argv[i] && (argv[i][0] == '-') && (argv[i][1] != 0); ++i ) {
if ( strcmp(argv[i], "--fullscreen") == 0 ) {
fullscreen = 1;
} else
if ((strcmp(argv[i], "--seek") == 0)||(strcmp(argv[i], "-S") == 0)) {
++i;
if ( argv[i] ) {
seek = atol(argv[i]);
}
} else
if ((strcmp(argv[i], "--volume") == 0)||(strcmp(argv[i], "-v") == 0)) {
++i;
if (i >= argc)
{
fprintf(stderr, "Please specify volume when using --volume or -v\n");
return(1);
}
if ( argv[i] ) {
volume = atoi(argv[i]);
}
if ( ( volume < 0 ) || ( volume 100 ) ) {
fprintf(stderr, "Volume must be between 0 and 100\n");
volume = 100;
}
}
else {
fprintf(stderr, "Warning: Unknown option: %s\n", argv[i]);
}
}
printf("\nuse video = %d, use audio = %d\n",use_video, use_audio);
printf("\ngoing to check input parameters\n");
if defined(linux) || defined(FreeBSD) /* Plaympeg doesn't need a mouse */
putenv("SDL_NOMOUSE=1");
endif
/* Play the mpeg files! */
status = 0;
for ( ; argv[i]; ++i ) {
/* Initialize SDL */
if ( use_video ) {
if ((SDL_Init(SDL_INIT_VIDEO) < 0) || !SDL_VideoDriverName(buf, 1)) {
fprintf(stderr, "Warning: Couldn't init SDL video: %s\n",
SDL_GetError());
fprintf(stderr, "Will ignore video stream\n");
use_video = 0;
}
printf("\ninitialised video\n");
}
if ( use_audio ) {
if ((SDL_Init(SDL_INIT_AUDIO) < 0) || !SDL_AudioDriverName(buf, 1)) {
fprintf(stderr, "Warning: Couldn't init SDL audio: %s\n",
SDL_GetError());
fprintf(stderr, "Will ignore audio stream\n");
use_audio = 0;
}
}
/* Allow Ctrl-C when there's no video output */
signal(SIGINT, next_movie);
printf("\nchecking defined supports\n");
/* Create the MPEG stream */
ifdef NET_SUPPORT
printf("\ndefined NET_SUPPORT\n");
ifdef HTTP_SUPPORT
printf("\ndefined HTTP_SUPPORT\n");
/* Check if source is an http URL */
printf("\nabout to call http_open\n");
printf("\nhere we go\n");
if((fd = http_open(argv[i])) != 0)
mpeg = SMPEG_new_descr(fd, &info, use_audio);
else
endif
endif
{
if(strcmp(argv[i], "-") == 0) /* Use stdin for input */
mpeg = SMPEG_new_descr(0, &info, use_audio);
else
mpeg = SMPEG_new(argv[i], &info, use_audio);
}
if ( SMPEG_error(mpeg) ) {
fprintf(stderr, "%s: %s\n", argv[i], SMPEG_error(mpeg));
SMPEG_delete(mpeg);
status = -1;
continue;
}
SMPEG_enableaudio(mpeg, use_audio);
SMPEG_enablevideo(mpeg, use_video);
SMPEG_setvolume(mpeg, volume);
/* Print information about the video */
basefile = strrchr(argv[i], '/');
if ( basefile ) {
++basefile;
} else {
basefile = argv[i];
}
if ( info.has_audio && info.has_video ) {
printf("%s: MPEG system stream (audio/video)\n", basefile);
} else if ( info.has_audio ) {
printf("%s: MPEG audio stream\n", basefile);
} else if ( info.has_video ) {
printf("%s: MPEG video stream\n", basefile);
}
if ( info.has_video ) {
printf("\tVideo %dx%d resolution\n", info.width, info.height);
}
if ( info.has_audio ) {
printf("\tAudio %s\n", info.audio_string);
}
if ( info.total_size ) {
printf("\tSize: %d\n", info.total_size);
}
if ( info.total_time ) {
printf("\tTotal time: %f\n", info.total_time);
}
/* Set up video display if needed */
if ( info.has_video && use_video ) {
const SDL_VideoInfo *video_info;
Uint32 video_flags;
int video_bpp;
int width, height;
/* Get the "native" video mode */
video_info = SDL_GetVideoInfo();
switch (video_info->vfmt->BitsPerPixel) {
case 16:
case 24:
case 32:
video_bpp = video_info->vfmt->BitsPerPixel;
break;
default:
video_bpp = 16;
break;
}
if ( scale_width ) {
width = scale_width;
} else {
width = info.width;
}
width *= scalesize;
if ( scale_height ) {
height = scale_height;
} else {
height = info.height;
}
height *= scalesize;
video_flags = SDL_SWSURFACE;
if ( fullscreen ) {
video_flags = SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_HWSURFACE;
}
video_flags |= SDL_ASYNCBLIT;
video_flags |= SDL_RESIZABLE;
screen = SDL_SetVideoMode(width, height, video_bpp, video_flags);
if ( screen == NULL ) {
fprintf(stderr, "Unable to set %dx%d video mode: %s\n",
width, height, SDL_GetError());
continue;
}
SDL_WM_SetCaption(argv[i], "plaympeg");
if ( screen->flags & SDL_FULLSCREEN ) {
SDL_ShowCursor(0);
}
SMPEG_setdisplay(mpeg, screen, NULL, update);
SMPEG_scaleXY(mpeg, screen->w, screen->h);
} else {
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
/* Set any special playback parameters */
if ( loop_play ) {
SMPEG_loop(mpeg, 1);
}
/* Seek starting position */
if(seek) SMPEG_seek(mpeg, seek);
/* Skip seconds to starting position */
if(skip) SMPEG_skip(mpeg, skip);
/* Play it, and wait for playback to complete */
SMPEG_play(mpeg);
done = 0;
pause = 0;
while ( ! done && ( pause || (SMPEG_status(mpeg) == SMPEG_PLAYING) ) ) {
SDL_Event event;
while ( use_video && SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_VIDEORESIZE: {
SDL_Surface *old_screen = screen;
SMPEG_pause(mpeg);
screen = SDL_SetVideoMode(event.resize.w, event.resize.h, screen->format->BitsPerPixel, screen->flags);
if ( old_screen != screen ) {
SMPEG_setdisplay(mpeg, screen, NULL, update);
}
SMPEG_scaleXY(mpeg, screen-w, screen-h);
SMPEG_pause(mpeg);
} break;
case SDL_KEYDOWN:
if ( (event.key.keysym.sym == SDLK_ESCAPE) || (event.key.keysym.sym == SDLK_q) ) {
// Quit
done = 1;
} else if ( event.key.keysym.sym == SDLK_RETURN ) {
// toggle fullscreen
if ( event.key.keysym.mod & KMOD_ALT ) {
SDL_WM_ToggleFullScreen(screen);
fullscreen = (screen-flags & SDL_FULLSCREEN);
SDL_ShowCursor(!fullscreen);
}
} else if ( event.key.keysym.sym == SDLK_UP ) {
// Volume up
if ( volume < 100 ) {
if ( event.key.keysym.mod & KMOD_SHIFT ) { // 10+
volume += 10;
} else if ( event.key.keysym.mod & KMOD_CTRL ) { // 100+
volume = 100;
} else { // 1+
volume++;
}
if ( volume 100 )
volume = 100;
SMPEG_setvolume(mpeg, volume);
}
} else if ( event.key.keysym.sym == SDLK_DOWN ) {
// Volume down
if ( volume 0 ) {
if ( event.key.keysym.mod & KMOD_SHIFT ) {
volume -= 10;
} else if ( event.key.keysym.mod & KMOD_CTRL ) {
volume = 0;
} else {
volume--;
}
if ( volume < 0 )
volume = 0;
SMPEG_setvolume(mpeg, volume);
}
} else if ( event.key.keysym.sym == SDLK_PAGEUP ) {
// Full volume
volume = 100;
SMPEG_setvolume(mpeg, volume);
} else if ( event.key.keysym.sym == SDLK_PAGEDOWN ) {
// Volume off
volume = 0;
SMPEG_setvolume(mpeg, volume);
} else if ( event.key.keysym.sym == SDLK_SPACE ) {
// Toggle play / pause
if ( SMPEG_status(mpeg) == SMPEG_PLAYING ) {
SMPEG_pause(mpeg);
pause = 1;
} else {
SMPEG_play(mpeg);
pause = 0;
}
} else if ( event.key.keysym.sym == SDLK_RIGHT ) {
// Forward
if ( event.key.keysym.mod & KMOD_SHIFT ) {
SMPEG_skip(mpeg, 100);
} else if ( event.key.keysym.mod & KMOD_CTRL ) {
SMPEG_skip(mpeg, 50);
} else {
SMPEG_skip(mpeg, 5);
}
} else if ( event.key.keysym.sym == SDLK_LEFT ) {
// Reverse
if ( event.key.keysym.mod & KMOD_SHIFT ) {
} else if ( event.key.keysym.mod & KMOD_CTRL ) {
} else {
}
} else if ( event.key.keysym.sym == SDLK_KP_MINUS ) {
// Scale minus
if ( scalesize > 1 ) {
scalesize--;
}
} else if ( event.key.keysym.sym == SDLK_KP_PLUS ) {
// Scale plus
scalesize++;
} else if ( event.key.keysym.sym == SDLK_f ) {
// Toggle filtering on/off
if ( bilinear_filtering ) {
SMPEG_Filter *filter = SMPEGfilter_null();
filter = SMPEG_filter( mpeg, filter );
filter-destroy(filter);
bilinear_filtering = 0;
} else {
SMPEG_Filter *filter = SMPEGfilter_bilinear();
filter = SMPEG_filter( mpeg, filter );
filter-destroy(filter);
bilinear_filtering = 1;
}
}
break;
case SDL_QUIT:
done = 1;
break;
default:
break;
}
}
SDL_Delay(1000/2);
}
SMPEG_delete(mpeg);
}
SDL_Quit();
if defined(HTTP_SUPPORT)
if(fd) close(fd);
endif
return(status);
}