finish roughing in ffmpeg_input

pull/3038/head
Isaac Connor 2017-06-26 16:55:49 -04:00
commit 62d6394923
15 changed files with 144 additions and 131 deletions

View File

@ -33,7 +33,7 @@
%global _hardened_build 1
Name: zoneminder
Version: 1.31.0
Version: 1.31.1
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons

View File

@ -4,61 +4,60 @@ set -e
if [ "$1" = "configure" ]; then
. /etc/zm/zm.conf
. /etc/zm/zm.conf
# The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group
chown www-data:root /var/log/zm
chown www-data:www-data /var/lib/zm
if [ -z "$2" ]; then
chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/*
fi
if [ ! -e "/etc/apache2/mods-enabled/cgi.load" ]; then
echo "The cgi module is not enabled in apache2. I am enabling it using a2enmod cgi."
a2enmod cgi
fi
# The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group
chown www-data:root /var/log/zm
chown www-data:www-data /var/lib/zm
if [ -z "$2" ]; then
chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/*
fi
if [ ! -e "/etc/apache2/mods-enabled/cgi.load" ]; then
echo "The cgi module is not enabled in apache2. I am enabling it using a2enmod cgi."
a2enmod cgi
fi
# Do this every time the package is installed or upgraded
# Ensure zoneminder is stopped
deb-systemd-invoke stop zoneminder.service || exit $?
if [ "$ZM_DB_HOST" = "localhost" ]; then
if [ -e "/etc/init.d/mysql" ]; then
if [ -e "/etc/init.d/mysql" ]; then
#
# Get mysql started if it isn't
#
if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then
deb-systemd-invoke start mysql.service || exit $?
fi
#
# Get mysql started if it isn't
#
if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then
deb-systemd-invoke start mysql.service || exit $?
fi
if $(/etc/init.d/mysql status >/dev/null 2>&1); then
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
# test if database if already present...
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
# This creates the user.
echo "grant lock tables,alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
else
echo "grant lock tables,alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
fi
# Ensure zoneminder is stopped
deb-systemd-invoke stop zoneminder.service || exit $?
zmupdate.pl --nointeractive
zmupdate.pl --nointeractive -f
echo "Done Updating, starting ZoneMinder"
deb-systemd-invoke start zoneminder.service || exit $?
else
echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.'
fi
if $(/etc/init.d/mysql status >/dev/null 2>&1); then
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
# test if database if already present...
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
# This creates the user.
echo "grant lock tables,alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
else
echo 'mysql not found, assuming remote server.'
echo "grant lock tables,alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
fi
zmupdate.pl --nointeractive
zmupdate.pl --nointeractive -f
else
echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.'
fi
else
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)"
echo 'mysql not found, assuming remote server.'
fi
else
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)"
fi
echo "Done Updating, starting ZoneMinder"
deb-systemd-invoke restart zoneminder.service || exit $?
fi
#DEBHELPER#

View File

@ -77,7 +77,7 @@ Source Path
Use this field to enter the full URL of the stream or file your camera supports. This is usually an RTSP url. There are several methods to learn this:
* Check the documentation that came with your camera
* Look for your camera in the hardware compatibilty list in the wiki http://wiki.zoneminder.com/Hardware_Compatibilty_List
* Look for your camera in the hardware compatibilty list in the wiki http://wiki.zoneminder.com/Hardware_Compatibility_List
* Try ZoneMinder's new ONVIF probe feature
* Download and install the ONVIF Device Manager onto a Windows machine https://sourceforge.net/projects/onvifdm/
* Use Google to find third party sites, such as ispy, which document this information

View File

@ -31,7 +31,6 @@
#include "zm.h"
#include "zm_db.h"
#include "zm_time.h"
#include "zm_mpeg.h"
#include "zm_signal.h"
#include "zm_event.h"
#include "zm_monitor.h"
@ -591,4 +590,3 @@ void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *
}
*/
}

View File

@ -35,12 +35,11 @@
#include "zm_signal.h"
#include "zm_event.h"
#include "zm_eventstream.h"
#include "zm_ffmpeg_input.h"
#include "zm_storage.h"
#include "zm_monitor.h"
#include "zm_sendfile.h"
//#define USE_PREPARED_SQL 1
bool EventStream::loadInitialEventData( int monitor_id, time_t event_time ) {
static char sql[ZM_SQL_SML_BUFSIZ];
@ -132,9 +131,13 @@ bool EventStream::loadEventData( int event_id ) {
event_data = new EventData;
event_data->event_id = event_id;
event_data->monitor_id = atoi( dbrow[0] );
event_data->start_time = atoi(dbrow[3]);
event_data->storage_id = dbrow[1] ? atoi( dbrow[1] ) : 0;
event_data->frame_count = dbrow[2] == NULL ? 0 : atoi(dbrow[2]);
event_data->start_time = atoi(dbrow[3]);
event_data->duration = atof(dbrow[4]);
strncpy( event_data->video_file, dbrow[5], sizeof( event_data->video_file )-1 );
mysql_free_result( result );
Storage * storage = new Storage( event_data->storage_id );
const char *storage_path = storage->Path();
@ -150,13 +153,9 @@ bool EventStream::loadEventData( int event_id ) {
else
snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%ld", staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, event_data->event_id );
}
event_data->frame_count = dbrow[2] == NULL ? 0 : atoi(dbrow[3]);
event_data->duration = atof(dbrow[4]);
strncpy( event_data->video_file, dbrow[5], sizeof( event_data->video_file )-1 );
updateFrameRate( (double)event_data->frame_count/event_data->duration );
mysql_free_result( result );
snprintf( sql, sizeof(sql), "select FrameId, unix_timestamp( `TimeStamp` ), Delta from Frames where EventId = %d order by FrameId asc", event_id );
if ( mysql_query( &dbconn, sql ) ) {
@ -209,10 +208,10 @@ bool EventStream::loadEventData( int event_id ) {
//}
if ( event_data->video_file[0] ) {
char *filepath[MAX_PATH];
snprintf( filepath, sizeof(filepath), "%s/%s", event_data->path, event_data->video_file[0] );
char filepath[PATH_MAX];
snprintf( filepath, sizeof(filepath), "%s/%s", event_data->path, event_data->video_file );
ffmpeg_input = new FFmpeg_Input();
if ( ! ffmpeg->Open() ) {
if ( ! ffmpeg_input->Open( filepath ) ) {
delete ffmpeg_input;
ffmpeg_input = NULL;
}
@ -248,15 +247,18 @@ void EventStream::processCommand( const CmdMsg *msg ) {
case CMD_PLAY :
{
Debug( 1, "Got PLAY command" );
if ( paused )
{
if ( paused ) {
// Clear paused flag
paused = false;
}
// If we are in single event mode and at the last frame, replay the current event
if ( (mode == MODE_SINGLE) && ((unsigned int)curr_frame_id == event_data->frame_count) )
if ( (mode == MODE_SINGLE) && ((unsigned int)curr_frame_id == event_data->frame_count) ) {
Debug(1, "Was in single_mode, and last frame, so jumping to 1st frame");
curr_frame_id = 1;
} else {
Debug(1, "mode is %s, current frame is %d, frame count is %d", (mode == MODE_SINGLE ? "single" : "not single" ), curr_frame_id, event_data->frame_count );
}
replay_rate = ZM_RATE_BASE;
break;
@ -381,7 +383,9 @@ void EventStream::processCommand( const CmdMsg *msg ) {
zoom = 500;
break;
}
send_frame = true;
break;
}
case CMD_ZOOMOUT :
{
@ -404,6 +408,7 @@ void EventStream::processCommand( const CmdMsg *msg ) {
zoom = 100;
break;
}
send_frame = true;
break;
}
case CMD_PAN :
@ -446,6 +451,7 @@ void EventStream::processCommand( const CmdMsg *msg ) {
int offset = ((unsigned char)msg->msg_data[1]<<24)|((unsigned char)msg->msg_data[2]<<16)|((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4];
curr_frame_id = (int)(event_data->frame_count*offset/event_data->duration);
Debug( 1, "Got SEEK command, to %d (new cfid: %d)", offset, curr_frame_id );
send_frame = true;
break;
}
case CMD_QUERY :
@ -476,13 +482,13 @@ void EventStream::processCommand( const CmdMsg *msg ) {
status_data.rate = replay_rate;
status_data.zoom = zoom;
status_data.paused = paused;
Debug( 2, "E:%d, P:%d, p:%d R:%d, Z:%d",
status_data.event,
status_data.paused,
status_data.progress,
status_data.rate,
status_data.zoom
);
Debug( 2, "Event:%d, Paused:%d, progress:%d Rate:%d, Zoom:%d",
status_data.event,
status_data.paused,
status_data.progress,
status_data.rate,
status_data.zoom
);
DataMsg status_msg;
status_msg.msg_type = MSG_DATA_EVENT;
@ -700,10 +706,10 @@ bool EventStream::sendFrame( int delta_us ) {
Error("Unable to send raw frame %u: %s",curr_frame_id,strerror(errno));
return( false );
}
#endif
#endif
fclose(fdj); /* Close the file handle */
} else {
fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size );
fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size );
if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) {
Error( "Unable to send stream frame: %s", strerror(errno) );
return( false );
@ -734,10 +740,13 @@ void EventStream::runStream() {
exit( 0 );
}
unsigned int delta_us = 0;
while( !zm_terminate ) {
gettimeofday( &now, NULL );
unsigned int delta_us = 0;
send_frame = false;
// commands may set send_frame to true
while(checkCommandQueue());
if ( step != 0 )
@ -773,17 +782,14 @@ void EventStream::runStream() {
}
//else
//{
usleep( STREAM_PAUSE_WAIT );
//curr_stream_time += (replay_rate>0?1:-1) * ((1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000));
curr_stream_time += (1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000);
usleep( STREAM_PAUSE_WAIT );
//curr_stream_time += (replay_rate>0?1:-1) * ((1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000));
curr_stream_time += (1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000);
//}
continue;
}
}
// Figure out if we should send this frame
bool send_frame = false;
if ( !paused ) {
// Figure out if we should send this frame
// If we are streaming and this frame is due to be sent
if ( ((curr_frame_id-1)%frame_mod) == 0 ) {
delta_us = (unsigned int)(frame_data->delta * 1000000);
@ -819,7 +825,8 @@ void EventStream::runStream() {
curr_frame_id = 1;
if ( send_frame && type != STREAM_MPEG ) {
Debug( 3, "dUs: %d", delta_us );
usleep( delta_us );
if ( delta_us )
usleep( delta_us );
}
} else {
usleep( (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))) );

View File

@ -20,24 +20,13 @@
#ifndef ZM_EVENTSTREAM_H
#define ZM_EVENTSTREAM_H
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <mysql/mysql.h>
#include <set>
#include <map>
#include "zm.h"
#include "zm_image.h"
#include "zm_stream.h"
#include "zm_video.h"
#include "zm_ffmpeg_input.h"
#ifdef __cplusplus
extern "C" {
@ -80,15 +69,15 @@ class EventStream : public StreamBase {
static const StreamMode DEFAULT_MODE = MODE_SINGLE;
protected:
StreamMode mode;
bool forceEventChange;
protected:
int curr_frame_id;
double curr_stream_time;
bool send_frame;
EventData *event_data;
FFmpeg_Input *ffmpeg_input;
protected:
bool loadEventData( int event_id );
@ -114,6 +103,7 @@ class EventStream : public StreamBase {
input_codec_context = 0;
input_codec = 0;
ffmpeg_input = NULL;
}
void setStreamStart( int init_event_id, unsigned int init_frame_id=0 ) {

View File

@ -1,13 +1,17 @@
#include "zm_ffmpeg_input.h"
#include "zm_logger.h"
#include "zm_ffmpeg.h"
void FFmpeg_Input() {
FFmpeg_Input::FFmpeg_Input() {
input_format_context = NULL;
video_stream_id = -1;
audio_stream_id = -1;
}
FFmpeg_Input::~FFmpeg_Input() {
}
int Open( const char *filepath ) {
int FFmpeg_Input::Open( const char *filepath ) {
int error;
@ -54,18 +58,18 @@ int Open( const char *filepath ) {
#endif
/** Find a decoder for the audio stream. */
if (!(streams[i].codec = avcodec_find_decoder((*input_format_context)->streams[i]->codecpar->codec_id))) {
if (!(streams[i].codec = avcodec_find_decoder(input_format_context->streams[i]->codecpar->codec_id))) {
Error( "Could not find input codec\n");
avformat_close_input(input_format_context);
avformat_close_input(&input_format_context);
return AVERROR_EXIT;
}
/** Open the decoder for the audio stream to use it later. */
if ((error = avcodec_open2( streams[i].context, streams[i].codec, NULL)) < 0) {
Errror( "Could not open input codec (error '%s')\n",
Error( "Could not open input codec (error '%s')\n",
av_make_error_string(error).c_str() );
avcodec_free_context( streams[i].context );
avformat_close_input(input_format_context);
avcodec_free_context( &streams[i].context );
avformat_close_input(&input_format_context);
return error;
}
@ -76,5 +80,5 @@ int Open( const char *filepath ) {
Debug( 3, "Unable to locate audio stream in %s", filepath );
return 0;
} // end int Open( const char * filepath )
} // end int FFmpeg::Open( const char * filepath )

View File

@ -32,6 +32,6 @@ class FFmpeg_Input {
int video_stream_id;
int audio_stream_id;
AVFormatContext *input_format_context;
}
};
#endif

View File

@ -8,30 +8,30 @@ extern "C" {
#ifdef HAVE_SENDFILE4_SUPPORT
#include <sys/sendfile.h>
int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) {
int err;
int err;
err = sendfile(out_fd, in_fd, offset, size);
if (err < 0)
return -errno;
err = sendfile(out_fd, in_fd, offset, size);
if (err < 0)
return -errno;
return err;
return err;
}
#elif HAVE_SENDFILE7_SUPPORT
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
int zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) {
int err;
err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0);
if (err && errno != EAGAIN)
return -errno;
int err;
err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0);
if (err && errno != EAGAIN)
return -errno;
if (size) {
*offset += size;
return size;
}
if (size) {
*offset += size;
return size;
}
return -EAGAIN;
return -EAGAIN;
}
#else
#error "Your platform does not support sendfile. Sorry."

View File

@ -112,6 +112,8 @@ int main( int argc, const char *argv[] ) {
char *value = strtok( NULL, "=" );
if ( !value )
value = (char *)"";
Debug(4, "Query string parameter (%s)=(%s)", name, value );
if ( !strcmp( name, "source" ) ) {
source = !strcmp( value, "event" )?ZMS_EVENT:ZMS_MONITOR;
} else if ( !strcmp( name, "mode" ) ) {
@ -187,7 +189,7 @@ int main( int argc, const char *argv[] ) {
if ( *auth ) {
user = zmLoadAuthUser( auth, config.auth_hash_ips );
} else {
Debug( 1, "Need both username and password" );
Debug( 1, "Need both username and password if auth not specified" );
}
}
//else if ( strcmp( config.auth_relay, "plain" ) == 0 )

View File

@ -72,6 +72,9 @@ public $defaults = array(
if ( ! isset( $this->{'terms'} ) ) {
if ( array_key_exists( 'Query', $this ) and $this->{'Query'} ) {
$this->{'terms'} = jsonDecode( $this->{'Query'} );
if ( isset( $this->{'terms'}['terms'] ) )
$this->{'terms'} = $this->{'terms'}['terms'];
} else {
$this->{'terms'} = array();
}

View File

@ -138,7 +138,7 @@ if ( !empty($action) ) {
} else {
$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
}
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['terms']));
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']));
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
$sql .= ', AutoUpload = '. ( !empty($_REQUEST['filter']['AutoUpload']) ? 1 : 0);

View File

@ -50,6 +50,7 @@ if ( isset( $_REQUEST['scale'] ) ) {
}
$replayModes = array(
'none' => translate('None'),
'single' => translate('ReplaySingle'),
'all' => translate('ReplayAll'),
'gapless' => translate('ReplayGapless'),
@ -64,9 +65,9 @@ if ( isset( $_REQUEST['replayMode'] ) )
$replayMode = validHtmlStr($_REQUEST['replayMode']);
if ( isset( $_COOKIE['replayMode']) && preg_match('#^[a-z]+$#', $_COOKIE['replayMode']) )
$replayMode = validHtmlStr($_COOKIE['replayMode']);
else {
$keys = array_keys( $replayModes );
$replayMode = array_shift( $keys );
if ( ( ! $replayMode ) or ( ! $replayModes[$replayMode] ) ) {
$replayMode = 'none';
}
// videojs zoomrotate only when direct recording
@ -188,8 +189,8 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
<input type="button" value="&lt;+" id="prevBtn" title="<?php echo translate('Prev') ?>" class="inactive" onclick="streamPrev( true );"/>
<input type="button" value="&lt;&lt;" id="fastRevBtn" title="<?php echo translate('Rewind') ?>" class="inactive" disabled="disabled" onclick="streamFastRev( true );"/>
<input type="button" value="&lt;" id="slowRevBtn" title="<?php echo translate('StepBack') ?>" class="unavail" disabled="disabled" onclick="streamSlowRev( true );"/>
<input type="button" value="||" id="pauseBtn" title="<?php echo translate('Pause') ?>" class="inactive" onclick="streamPause( true );"/>
<input type="button" value="|>" id="playBtn" title="<?php echo translate('Play') ?>" class="active" disabled="disabled" onclick="streamPlay( true );"/>
<input type="button" value="||" id="pauseBtn" title="<?php echo translate('Pause') ?>" class="inactive" onclick="pauseClicked();"/>
<input type="button" value="|>" id="playBtn" title="<?php echo translate('Play') ?>" class="active" disabled="disabled" onclick="playClicked();"/>
<input type="button" value="&gt;" id="slowFwdBtn" title="<?php echo translate('StepForward') ?>" class="unavail" disabled="disabled" onclick="streamSlowFwd( true );"/>
<input type="button" value="&gt;&gt;" id="fastFwdBtn" title="<?php echo translate('FastForward') ?>" class="inactive" disabled="disabled" onclick="streamFastFwd( true );"/>
<input type="button" value="&ndash;" id="zoomOutBtn" title="<?php echo translate('ZoomOut') ?>" class="avail" onclick="streamZoomOut();"/>
@ -209,7 +210,7 @@ if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
</div>
</div>
<?php
if ( $Event->SaveJPEGs() & 3 ) { // frames or analysis
if ( $Event->SaveJPEGs() & 3 ) { // frames or analysis
?>
<div id="eventStills" class="hidden">
<div id="eventThumbsPanel">

View File

@ -168,6 +168,7 @@ if ( (null !== $filter->Concurrent()) and $filter->Concurrent() )
<table id="fieldsTable" class="filterTable">
<tbody>
<?php
var_dump($terms);
for ( $i = 0; $i < count($terms); $i++ ) {
$term = $terms[$i];
if ( ! isset( $term['op'] ) )

View File

@ -4,6 +4,8 @@ function setButtonState( element, butClass ) {
if ( element ) {
element.className = butClass;
element.disabled = (butClass != 'inactive');
} else {
console.log("Element was null in setButtonState");
}
}
@ -58,16 +60,15 @@ function getCmdResponse( respObj, respText ) {
lastEventId = eventId;
}
if ( streamStatus.paused == true ) {
console.log('paused');
$('modeValue').set( 'text', "Paused" );
$('modeValue').set( 'text', 'Paused' );
$('rate').addClass( 'hidden' );
streamPause( false );
streamPause( );
} else {
console.log('playing');
$('modeValue').set( 'text', "Replay" );
$('rateValue').set( 'text', streamStatus.rate );
$('rate').removeClass( 'hidden' );
streamPlay( false );
streamPlay( );
}
$('progressValue').set( 'text', secsToTime( parseInt(streamStatus.progress) ) );
$('zoomValue').set( 'text', streamStatus.zoom );
@ -90,17 +91,25 @@ function getCmdResponse( respObj, respText ) {
var streamReq = new Request.JSON( { url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'chain', onSuccess: getCmdResponse } );
function streamPause( action ) {
function pauseClicked( ) {
streamReq.send( streamParms+"&command="+CMD_PAUSE );
}
// Called when stream becomes paused, just updates the button status
function streamPause( ) {
setButtonState( $('pauseBtn'), 'active' );
setButtonState( $('playBtn'), 'inactive' );
setButtonState( $('fastFwdBtn'), 'unavail' );
setButtonState( $('slowFwdBtn'), 'inactive' );
setButtonState( $('slowRevBtn'), 'inactive' );
setButtonState( $('fastRevBtn'), 'unavail' );
streamReq.send( streamParms+"&command="+CMD_PAUSE );
}
function streamPlay( action ) {
function playClicked( ) {
streamReq.send( streamParms+"&command="+CMD_PLAY );
}
function streamPlay( ) {
setButtonState( $('pauseBtn'), 'inactive' );
if (streamStatus)
setButtonState( $('playBtn'), streamStatus.rate==1?'active':'inactive' );
@ -108,7 +117,6 @@ function streamPlay( action ) {
setButtonState( $('slowFwdBtn'), 'unavail' );
setButtonState( $('slowRevBtn'), 'unavail' );
setButtonState( $('fastRevBtn'), 'inactive' );
streamReq.send( streamParms+"&command="+CMD_PLAY );
}
function streamFastFwd( action ) {