Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
GStreamer_audioRecorder
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
m3
GStreamer_audioRecorder
Commits
820dc52c
Commit
820dc52c
authored
7 years ago
by
d.basulto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
restart the connection and save partial buffer
parent
e0753bee
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
226 additions
and
213 deletions
+226
-213
StreamRecorder.cpp
StreamRecorder.cpp
+175
-169
StreamRecorder.h
StreamRecorder.h
+45
-39
StreamRecorder.o
StreamRecorder.o
+0
-0
main.cpp
main.cpp
+6
-5
main.o
main.o
+0
-0
No files found.
StreamRecorder.cpp
View file @
820dc52c
...
...
@@ -13,87 +13,119 @@
#include <ctime>
#include <cmath>
#include <sstream>
//#include <thread>
#include "FLAC/metadata.h"
#include "FLAC/stream_encoder.h"
#include <cstring>
using
namespace
std
;
//------------------------------------------------------------------------------
/**
* Constructor
* @param source streaing url
* @param time split recording in segments of time seconds.
*/
StreamRecorder
::
StreamRecorder
(
const
char
*
source
,
int
time
)
{
StreamRecorder
::
StreamRecorder
(
const
char
*
source
,
int
time
)
{
int
nFrames
=
ceil
(
time
*
STREAMRECORDER_SAMPLERATE
/
READSIZE
);
recordTime
=
nFrames
*
READSIZE
/
STREAMRECORDER_SAMPLERATE
;
cout
<<
"record time: "
<<
recordTime
<<
endl
;
// buffer size
bufferSize
=
nFrames
*
READSIZE
*
STREAMRECORDER_BYTESPERSAMPLE
;
// buffer that ig going to contain the audio
audioBuffer
=
new
unsigned
char
[
bufferSize
];
// Puts all the elements in audio buffer in 0
memset
(
audioBuffer
,
0
,
bufferSize
);
// set the pointer to the actual position of the buffer;
audioBufferPosition
=
audioBuffer
;
// Bytes saved counter
nBytes
=
0
;
// flag that save the conncetion state
isConnectionLost
=
false
;
// Create the elements and sets capabilities
createMainPipeline
();
// Connec with the URI
connect
(
source
);
}
//------------------------------------------------------------------------------
/**
* Connect to the stream
* @param uri streaing uri
* @return unimplemented
*/
int
StreamRecorder
::
connect
(
const
char
*
uri
)
{
int
StreamRecorder
::
connect
(
const
char
*
uri
)
{
disconnect
();
cout
<<
"connecting to "
<<
uri
<<
endl
;
gst_element_set_state
(
mainPipeline
,
GST_STATE_NULL
);
// Uri destiny
pluginUri
=
(
char
*
)
uri
;
gst_element_set_state
(
mainPipeline
,
GST_STATE_NULL
);
gst_element_set_state
(
mainPipeline
,
GST_STATE_READY
);
// Assign the uri property
g_object_set
(
G_OBJECT
(
streamSrc
),
"uri"
,
uri
,
NULL
);
gst_element_link
(
streamSrc
,
audioConvert
);
// Main pipeline starts to work
gst_element_set_state
(
mainPipeline
,
GST_STATE_PLAYING
);
return
0
;
}
//------------------------------------------------------------------------------
/**
* disconnect from the stream
* @return unimplemented
*/
int
StreamRecorder
::
disconnect
()
{
int
StreamRecorder
::
disconnect
()
{
gst_element_unlink
(
streamSrc
,
audioConvert
);
gst_element_set_state
(
mainPipeline
,
GST_STATE_NULL
);
return
0
;
}
//------------------------------------------------------------------------------
/**
* Create main pipeline
* @return 0 on succe
e
ss else on error
* @return 0 on success else on error
*/
int
StreamRecorder
::
createMainPipeline
()
{
mainPipeline
=
gst_pipeline_new
(
"stream-recorder"
);
int
StreamRecorder
::
createMainPipeline
()
{
mainPipeline
=
gst_pipeline_new
(
"stream-recorder"
);
GstBus
*
bus
;
bus
=
gst_pipeline_get_bus
(
GST_PIPELINE
(
mainPipeline
));
gst_bus_add_watch
(
bus
,
bus_callback
,
NULL
);
gst_bus_add_watch
(
bus
,
bus_callback
,
this
);
gst_object_unref
(
GST_OBJECT
(
bus
));
streamSrc
=
gst_element_factory_make
(
"uridecodebin"
,
"stream_source"
);
audioConvert
=
gst_element_factory_make
(
"audioconvert"
,
"audio_convert"
);
audioResample
=
gst_element_factory_make
(
"audioresample"
,
"audio_resample"
);
//
audioResample = gst_element_factory_make ("audioresample", "audio_resample");
filterCaps
=
gst_element_factory_make
(
"capsfilter"
,
"filter_cap"
);
GstCaps
*
fc
=
gst_caps_new_full
(
gst_structure_new
(
"audio/x-raw"
,
"channels"
,
G_TYPE_INT
,
1
,
"rate"
,
G_TYPE_INT
,
STREAMRECORDER_SAMPLERATE
,
// "width", G_TYPE_INT, 16,
// "depth", G_TYPE_INT, 16,
"format"
,
G_TYPE_STRING
,
"S16LE"
,
"signed"
,
G_TYPE_BOOLEAN
,
1
,
//MUST BE SIGNED
"endianness"
,
G_TYPE_INT
,
1234
,
NULL
),
NULL
);
"channels"
,
G_TYPE_INT
,
1
,
"rate"
,
G_TYPE_INT
,
STREAMRECORDER_SAMPLERATE
,
"format"
,
G_TYPE_STRING
,
"S16LE"
,
"signed"
,
G_TYPE_BOOLEAN
,
1
,
//MUST BE SIGNED
"endianness"
,
G_TYPE_INT
,
1234
,
NULL
),
NULL
);
g_object_set
(
G_OBJECT
(
filterCaps
),
"caps"
,
fc
,
NULL
);
queue0
=
gst_element_factory_make
(
"queue"
,
"queue0"
);
...
...
@@ -102,27 +134,33 @@ int StreamRecorder::createMainPipeline()
queue1
=
gst_element_factory_make
(
"queue"
,
"queue1"
);
fakeSink
=
gst_element_factory_make
(
"fakesink"
,
"fake_sink"
);
audioSink
=
gst_element_factory_make
(
"autoaudiosink"
,
"speaker"
);
// g_object_set (G_OBJECT (fakeSink), "signal-handoffs", TRUE, NULL);
// g_signal_connect(fakeSink, "handoff", G_CALLBACK(buffer_callback), this);
//// g_object_set (G_OBJECT (tmpFileSink), "location", str.c_str(), NULL);
// compressor = gst_element_factory_make("vorbisenc", "audio_compressor");
//audioSink = gst_element_factory_make("autoaudiosink", "speaker");
gst_bin_add_many
(
GST_BIN
(
mainPipeline
),
streamSrc
,
audioConvert
,
filterCaps
,
queue0
,
filter
,
queue1
,
fakeSink
,
NULL
);
if
(
!
gst_element_link_many
(
audioConvert
,
filterCaps
,
queue0
,
filter
,
queue1
,
fakeSink
,
NULL
))
// gst_bin_add_many (GST_BIN (mainPipeline), streamSrc, audioConvert, filterCaps, queue0, filter, queue1, audioSink, NULL);
// if(!gst_element_link_many(audioConvert, filterCaps, queue0, filter, queue1, audioSink, NULL))
{
gst_bin_add_many
(
GST_BIN
(
mainPipeline
),
streamSrc
,
audioConvert
,
filterCaps
,
queue0
,
filter
,
queue1
,
fakeSink
,
NULL
);
if
(
!
gst_element_link_many
(
audioConvert
,
filterCaps
,
queue0
,
filter
,
queue1
,
fakeSink
,
NULL
)){
//gst_bin_add_many (GST_BIN (mainPipeline), streamSrc, audioConvert, filterCaps, queue0, filter, queue1, audioSink, NULL);
//if(!gst_element_link_many(audioConvert, filterCaps, queue0, filter, queue1, audioSink, NULL)){
cerr
<<
"mainPipeline: Failed to link elements in the pipeline"
<<
endl
;
exit
(
0
);
return
1
;
}
g_signal_connect
(
streamSrc
,
"pad-added"
,
G_CALLBACK
(
srcNewPad_callback
),
this
);
gst_element_set_state
(
mainPipeline
,
GST_STATE_NULL
);
return
0
;
}
//------------------------------------------------------------------------------
gboolean
StreamRecorder
::
reconnectURIStream
(
void
*
instance
){
cout
<<
"Restarting the main pipeline"
<<
endl
;
((
StreamRecorder
*
)
instance
)
->
connect
(((
StreamRecorder
*
)
instance
)
->
pluginUri
);
return
FALSE
;
}
//------------------------------------------------------------------------------
/**
* disconnect from the stream
* @param the GstBus that sent the message
...
...
@@ -130,126 +168,124 @@ int StreamRecorder::createMainPipeline()
* @param user_data NULL
* @return unimplemented
*/
int
StreamRecorder
::
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
user_data
)
{
printf
(
"StreamRecorder got %s message
\n
"
,
GST_MESSAGE_TYPE_NAME
(
message
));
switch
(
GST_MESSAGE_TYPE
(
message
))
{
case
GST_MESSAGE_EOS
:
int
StreamRecorder
::
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
user_data
)
{
//printf("StreamRecorder got %s message\n", GST_MESSAGE_TYPE_NAME (message));
if
(
GST_MESSAGE_TYPE
(
message
)
==
GST_MESSAGE_EOS
){
((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
=
true
;
}
switch
(
GST_MESSAGE_TYPE
(
message
))
{
case
GST_MESSAGE_EOS
:
cout
<<
"End of stream"
<<
endl
;
//&g_main_loop_quit (loop)
;
cout
<<
"End sometimes src"
<<
endl
;
break
;
case
GST_MESSAGE_ERROR
:
gchar
*
debug
;
GError
*
error
;
gst_message_parse_error
(
message
,
&
error
,
&
debug
);
g_free
(
debug
);
// Print specific error
cerr
<<
"Error: "
<<
error
->
message
<<
endl
;
g_error_free
(
error
);
//g_main_loop_quit (loop);
// Try to reconnect with the uri stream
g_timeout_add
(
60
*
1000
,
reconnectURIStream
,
user_data
);
// Enter only if the connection is lost
if
(((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
){
savePartialBuffer
(
user_data
);
((
StreamRecorder
*
)
user_data
)
->
isConnectionLost
=
false
;
}
break
;
default
:
default
:
break
;
}
return
TRUE
;
}
//------------------------------------------------------------------------------
void
StreamRecorder
::
savePartialBuffer
(
void
*
user_data
){
// Calculate the number of bytes that are missing for reach the max buffer size
// The buffer size is obtained based on the maximum recording time
int
missingBytes
=
((
StreamRecorder
*
)
user_data
)
->
bufferSize
-
((
StreamRecorder
*
)
user_data
)
->
nBytes
;
// Put the buffer position in the last position of the buffer
((
StreamRecorder
*
)
user_data
)
->
audioBufferPosition
+=
missingBytes
;
// Save in flac format
((
StreamRecorder
*
)
user_data
)
->
compressBuffer
();
// Restart the possition pointer
((
StreamRecorder
*
)
user_data
)
->
audioBufferPosition
=
((
StreamRecorder
*
)
user_data
)
->
audioBuffer
;
// Restart the buffer default values
memset
(((
StreamRecorder
*
)
user_data
)
->
audioBuffer
,
0
,
((
StreamRecorder
*
)
user_data
)
->
bufferSize
);
((
StreamRecorder
*
)
user_data
)
->
nBytes
=
0
;
}
//------------------------------------------------------------------------------
/**
* CallBack to link the pads created by uridecodebin
* @param element The uridecodebin element
* @param pad The pad added
* @param data this
*/
void
StreamRecorder
::
srcNewPad_callback
(
GstElement
*
element
,
GstPad
*
pad
,
void
*
data
)
{
void
StreamRecorder
::
srcNewPad_callback
(
GstElement
*
element
,
GstPad
*
pad
,
void
*
data
)
{
cout
<<
gst_element_get_name
(
element
)
<<
" adding pad.."
<<
gst_pad_get_name
(
pad
)
<<
endl
;
cout
<<
"Pad Name: "
<<
gst_pad_get_name
(
pad
)
<<
endl
;
// ((StreamRecorder*)data)->printCaps(pad);
GstPad
*
sinkpad
;
// gst_pad_get_caps is for gst v0.1
// gst_pad_get_caps is for gst v0.1
//GstCaps *new_pad_caps = gst_pad_get_caps (pad);
GstCaps
*
new_pad_caps
=
gst_pad_query_caps
(
pad
,
NULL
);
GstStructure
*
new_pad_struct
=
gst_caps_get_structure
(
new_pad_caps
,
0
);
const
gchar
*
new_pad_type
=
gst_structure_get_name
(
new_pad_struct
);
if
(
g_str_has_prefix
(
new_pad_type
,
"audio/x-raw"
))
{
cout
<<
"linking "
<<
new_pad_type
<<
endl
;
if
(
g_str_has_prefix
(
new_pad_type
,
"audio/x-raw"
))
{
cout
<<
"linking "
<<
new_pad_type
<<
endl
;
GstElement
*
nextElement
=
((
StreamRecorder
*
)
data
)
->
audioConvert
;
sinkpad
=
gst_element_get_static_pad
(
nextElement
,
"sink"
);
if
(
GST_PAD_LINK_FAILED
(
gst_pad_link
(
pad
,
sinkpad
)))
{
cerr
<<
"
\t
Type is "
<<
new_pad_type
<<
" but link failed."
<<
endl
;
if
(
GST_PAD_LINK_FAILED
(
gst_pad_link
(
pad
,
sinkpad
)))
{
cerr
<<
"Type is "
<<
new_pad_type
<<
" but link failed."
<<
endl
;
exit
(
0
);
}
else
{
cout
<<
"
\t
Link succeeded "
<<
new_pad_type
<<
endl
;
else
{
cout
<<
"Link succeeded "
<<
new_pad_type
<<
endl
;
}
}
}
//------------------------------------------------------------------------------
/**
* Save audio data in wav format
* @param data Audio buffer
* @param length Buffer length
* @return unimplemented
*/
int
StreamRecorder
::
saveWav
(
unsigned
char
*
data
,
int
length
)
const
{
cout
<<
"saveWav:"
<<
length
<<
endl
;
unsigned
char
*
newData
=
new
unsigned
char
[
length
];
memcpy
(
newData
,
data
,
length
);
stringstream
ss
;
string
fileNameStr
;
ss
<<
time
(
NULL
)
<<
".wav"
<<
endl
;
getline
(
ss
,
fileNameStr
);
ofstream
myFile
;
int
size
=
36
+
length
;
int
subSize
=
16
;
short
format
=
1
;
short
channels
=
1
;
int
sampleRate
=
STREAMRECORDER_SAMPLERATE
;
int
byteRate
=
sampleRate
*
channels
*
STREAMRECORDER_BYTESPERSAMPLE
;
short
blockAlign
=
channels
*
STREAMRECORDER_BYTESPERSAMPLE
;
short
bitsPerSample
=
STREAMRECORDER_BYTESPERSAMPLE
*
8
;
int
dataSize
=
length
;
myFile
.
open
(
fileNameStr
.
c_str
(),
std
::
ios
::
binary
);
myFile
.
write
(
"RIFF"
,
4
);
myFile
.
write
((
char
*
)
&
size
,
sizeof
(
int
));
myFile
.
write
(
"WAVE"
,
4
);
myFile
.
write
(
"fmt "
,
4
);
myFile
.
write
((
char
*
)
&
subSize
,
sizeof
(
int
));
myFile
.
write
((
char
*
)
&
format
,
sizeof
(
short
));
// Format (1 = PCM)
myFile
.
write
((
char
*
)
&
channels
,
sizeof
(
short
));
// Channels
myFile
.
write
((
char
*
)
&
sampleRate
,
sizeof
(
int
));
// Sample Rate
myFile
.
write
((
char
*
)
&
byteRate
,
sizeof
(
int
));
// Byterate
myFile
.
write
((
char
*
)
&
blockAlign
,
sizeof
(
short
));
// Frame size
myFile
.
write
((
char
*
)
&
bitsPerSample
,
sizeof
(
short
));
// Bits per sample
myFile
.
write
(
"data"
,
4
);
myFile
.
write
((
char
*
)
&
dataSize
,
sizeof
(
int
));
myFile
.
write
((
char
*
)
newData
,
dataSize
);
myFile
.
close
();
delete
[]
newData
;
return
0
;
}
//------------------------------------------------------------------------------
/**
* Save audio data (audioBuffer) in flac format
* @return unimplemented
*/
int
StreamRecorder
::
compressBuffer
()
{
long
int
currentTime
=
time
(
NULL
);
...
...
@@ -268,7 +304,6 @@ int StreamRecorder::compressBuffer()
FLAC__StreamMetadata_VorbisComment_Entry
entry
;
FLAC__StreamEncoderInitStatus
init_status
;
/* allocate the encoder */
if
((
encoder
=
FLAC__stream_encoder_new
())
==
NULL
)
{
...
...
@@ -362,45 +397,47 @@ int StreamRecorder::compressBuffer()
delete
[]
pcm
;
return
0
;
}
//------------------------------------------------------------------------------
/**
* Add audio data to audioBuffer
* @param data Audio data to add
* @param length Data length
* @return Bytes writen
*/
int
StreamRecorder
::
addToBuffer
(
unsigned
char
*
data
,
int
length
)
{
// cout << "addToBuffer("<<length<<")" << endl;
int
StreamRecorder
::
addToBuffer
(
unsigned
char
*
data
,
int
length
)
{
//cout << "addToBuffer(" << length << ")" << endl;
int
bytesRead
=
length
;
// READSIZE*STREAMRECORDER_BYTESPERSAMPLE;
memcpy
((
char
*
)
audioBufferPosition
,
(
char
*
)
data
,
bytesRead
);
audioBufferPosition
+=
bytesRead
;
cout
<<
*
audioBufferPosition
<<
endl
;
audioBufferPosition
+=
bytesRead
;
nBytes
+=
bytesRead
;
//READSIZE;
// if(nBytes*STREAMRECORDER_BYTESPERSAMPLE >= bufferSize)
if
(
nBytes
>=
bufferSize
)
{
//// cout << " send to compress:" << nBytes << endl;
//saveWav(audioBuffer, bufferSize);
cout
<<
"Bytes readed "
<<
nBytes
<<
endl
;
cout
<<
"Buffer size "
<<
bufferSize
<<
endl
;
if
(
nBytes
>=
bufferSize
)
{
compressBuffer
();
audioBufferPosition
=
audioBuffer
;
memset
(
audioBuffer
,
0
,
bufferSize
);
nBytes
=
0
;
}
// else
// {
// cout << "Size dont match: "<< nBytes << " >= " << bufferSize << endl<< endl;
// }
return
nBytes
;
}
//------------------------------------------------------------------------------
void
StreamRecorder
::
buffer_callback
(
GstElement
*
fakesink
,
GstBuffer
*
buffer
,
GstPad
*
pad
,
gpointer
user_data
)
{
// cout << "Buffer_callback" << endl;
// cout<<(char*)buffer<<endl;
// ((StreamRecorder*)user_data)->addToBuffer((unsigned short*)buffer);
}
//------------------------------------------------------------------------------
/**
* CallBack for handoff signal of identity filter
* @param filter Identity filter
...
...
@@ -408,53 +445,22 @@ void StreamRecorder::buffer_callback(GstElement *fakesink, GstBuffer *buffer, Gs
* @param user_data this
* @return unimplemented
*/
int
StreamRecorder
::
filter_handoff_callback
(
GstElement
*
filter
,
GstBuffer
*
buffer
,
void
*
user_data
)
{
// cout << "filter_handoff_callback
" << endl;
cout
<<
"LLEGO INFO
"
<<
endl
;
GstMapInfo
info
;
if
(
!
gst_buffer_map
(
buffer
,
&
info
,
GST_MAP_READ
))
{
if
(
!
gst_buffer_map
(
buffer
,
&
info
,
GST_MAP_READ
))
{
cout
<<
"ERROR: MAPPING IS NOT VALID"
<<
endl
;
}
//GST_BUFFER_DATA is for gst v0.1
//((StreamRecorder*)user_data)->addToBuffer((unsigned char*)GST_BUFFER_DATA (buffer));
// user data is the class
((
StreamRecorder
*
)
user_data
)
->
addToBuffer
((
unsigned
char
*
)
info
.
data
,
info
.
size
);
gst_buffer_unmap
(
buffer
,
&
info
);
return
0
;
}
//------------------------------------------------------------------------------
/**
* Print pad capabilities
* @param pad pad
*/
void
StreamRecorder
::
printCaps
(
GstPad
*
pad
)
{
// guint32 format;
//GstCaps *padCaps = gst_pad_get_caps(pad);
GstCaps
*
padCaps
=
gst_pad_query_caps
(
pad
,
NULL
);
unsigned
int
nCaps
=
gst_caps_get_size
(
padCaps
);
const
GstStructure
*
str
;
cout
<<
nCaps
<<
" capabilities detected"
<<
endl
;
cout
<<
gst_caps_to_string
(
padCaps
)
<<
endl
;
for
(
unsigned
int
i
=
0
;
i
<
nCaps
;
i
++
)
{
cout
<<
" Capability: "
<<
i
<<
endl
;
str
=
gst_caps_get_structure
(
padCaps
,
i
);
int
nFields
=
gst_structure_n_fields
(
str
);
cout
<<
gst_structure_get_name
(
str
)
<<
": fields = "
<<
nFields
<<
endl
;
// for(int n=0; n < nFields; n++)
// {
// const char* name = gst_structure_nth_field_name(str, n);
// cout << name << endl;
// cout << G_VALUE_TYPE(gst_structure_get_value (str, name))<< endl;
// }
// cout << ": "<< width << "x" << height<< " @ " << fpsNumerator <<"/" <<fpsDenominator <<" : "<< depth << " bits, " << endl;
}
}
//------------------------------------------------------------------------------
This diff is collapsed.
Click to expand it.
StreamRecorder.h
View file @
820dc52c
...
...
@@ -14,6 +14,7 @@
// your public header include
//------------------------------------------------------------------------------
#include <gst/gst.h>
#include <jmorecfg.h>
//------------------------------------------------------------------------------
#define STREAMRECORDER_SAMPLERATE 44100
#define READSIZE 1152 //For MPEG1, frame_size = 1152 samples/frame
...
...
@@ -22,46 +23,51 @@
//------------------------------------------------------------------------------
class
StreamRecorder
{
private
:
unsigned
int
nBytes
;
unsigned
int
bufferSize
;
unsigned
char
*
audioBuffer
;
unsigned
char
*
audioBufferPosition
;
int
recordTime
;
char
*
sourceName
;
GstElement
*
streamSrc
;
GstElement
*
audioConvert
;
GstElement
*
audioResample
;
GstElement
*
filterCaps
;
GstElement
*
queue0
;
GstElement
*
queue1
;
GstElement
*
filter
;
// GstElement* compressor;
// GstElement* queue2;
// GstElement* muxer;
// GstElement* fileSink;
GstElement
*
fakeSink
;
GstElement
*
audioSink
;
GstElement
*
mainPipeline
;
// GstElement* sinkPipeline;
private
:
GstElement
*
tempBin
;
int
createMainPipeline
();
// int createSinkPipeline();
int
connect
(
const
char
*
uri
);
int
disconnect
();
static
void
srcNewPad_callback
(
GstElement
*
element
,
GstPad
*
pad
,
void
*
data
);
static
int
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
data
);
// static void block_async_cb (GstPad * pad, gboolean blocked, gpointer user_data);
static
void
buffer_callback
(
GstElement
*
fakesink
,
GstBuffer
*
buffer
,
GstPad
*
pad
,
gpointer
user_data
);
static
int
filter_handoff_callback
(
GstElement
*
filter
,
GstBuffer
*
buffer
,
void
*
user_data
);
int
addToBuffer
(
unsigned
char
*
data
,
int
length
);
int
compressBuffer
();
int
saveWav
(
unsigned
char
*
data
,
int
size
)
const
;
void
printCaps
(
GstPad
*
pad
);
public
:
StreamRecorder
(
const
char
*
source
,
int
time
);
unsigned
int
nBytes
;
unsigned
int
bufferSize
;
unsigned
char
*
audioBuffer
;
unsigned
char
*
audioBufferPosition
;
int
recordTime
;
bool
isConnectionLost
;
char
*
pluginUri
;
//char* sourceName;
GstElement
*
streamSrc
;
GstElement
*
audioConvert
;
//GstElement* audioResample;
GstElement
*
filterCaps
;
GstElement
*
queue0
;
GstElement
*
queue1
;
GstElement
*
filter
;
GstElement
*
fakeSink
;
//GstElement* audioSink;
GstElement
*
mainPipeline
;
//GstElement* tempBin;
int
createMainPipeline
();
int
connect
(
const
char
*
uri
);
int
disconnect
();
// callbacks
static
void
srcNewPad_callback
(
GstElement
*
element
,
GstPad
*
pad
,
void
*
data
);
static
int
bus_callback
(
GstBus
*
bus
,
GstMessage
*
message
,
void
*
data
);
static
int
filter_handoff_callback
(
GstElement
*
filter
,
GstBuffer
*
buffer
,
void
*
user_data
);
// add data to buffer
int
addToBuffer
(
unsigned
char
*
data
,
int
length
);
int
compressBuffer
();
// Save information when connection fails
static
void
savePartialBuffer
(
void
*
user_data
);
// Restart the pipeline
static
gboolean
reconnectURIStream
(
void
*
data
);
public
:
StreamRecorder
(
const
char
*
source
,
int
time
);
};
//------------------------------------------------------------------------------
#endif
This diff is collapsed.
Click to expand it.
StreamRecorder.o
View file @
820dc52c
No preview for this file type
This diff is collapsed.
Click to expand it.
main.cpp
View file @
820dc52c
...
...
@@ -8,19 +8,20 @@
#include "StreamRecorder.h"
using
namespace
std
;
//------------------------------------------------------------------------------
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
<
2
)
{
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
<
3
)
{
cerr
<<
"too few arguments"
<<
endl
;
return
EXIT_FAILURE
;
}
gst_init
(
&
argc
,
&
argv
);
StreamRecorder
myRecorder
=
StreamRecorder
(
argv
[
1
],
atoi
(
argv
[
2
]));
GMainLoop
*
main_loop
=
NULL
;
main_loop
=
g_main_loop_new
(
NULL
,
FALSE
);
g_main_loop_run
(
main_loop
);
return
0
;
return
0
;
}
//------------------------------------------------------------------------------
This diff is collapsed.
Click to expand it.
main.o
View file @
820dc52c
No preview for this file type
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment