GStreamer GstBusSyncHandler Stop, Pause and Play States - wxwidgets

I use Gstreamer as base for playing videos and audio and so far its working fine. Now I want to know when media is stopped, paused, loaded or started playing and notify the GUI. Now the Messages keep repeating itself (see the attached image). Now in that situation, it will be flooding my GUI. I want to receive event only once (for example when media is stopped or pause or loaded).
The only Message that I get consistently (once) is End of Stream.
Is there a way to get the said message only once, when they happen?
Here is my current code
extern "C"
{
static GstBusSyncReply
bus_sync(GstBus* bus, GstMessage* message, gpointer user_data)
{
CustomData* data = reinterpret_cast<CustomData*>(user_data);
GstState old_state, new_state, pending;
gst_message_parse_state_changed(message, &old_state, &new_state, &pending);
g_print ("State set from %s to %s --- %s\n", gst_element_state_get_name (old_state), gst_element_state_get_name (new_state), gst_element_state_get_name (pending));
switch(GST_MESSAGE_TYPE(message))
{
case GST_MESSAGE_STATE_CHANGED:
{
wxGStreamer* win = dynamic_cast<wxGStreamer*>(data->parent);
if(win)
{
win->SendMessage(wxMEDIASTATE_CHANGED);
}
if(data->state!=new_state)
{
//state changed, save it
data->state = new_state;
if(old_state==GST_STATE_NULL && new_state == GST_STATE_READY && pending== GST_STATE_PLAYING)
{
g_print ("***Loaded***\n");
}
else if(old_state==GST_STATE_PLAYING && new_state == GST_STATE_PAUSED && pending== GST_STATE_VOID_PENDING)
{
g_print ("***Paused***\n");
}
else if(old_state==GST_STATE_READY && new_state == GST_STATE_NULL && pending== GST_STATE_VOID_PENDING)
{
g_print ("***Stopped***\n");
}
else if(new_state == GST_STATE_PLAYING &&(old_state==GST_STATE_READY||old_state==GST_STATE_PAUSED) )
{
g_print ("***Playing***\n");
}
}
break;
}
}
}
}

Simply answered: you get more messages from GstBus other than play/stop states.
Implement a switch in your code and your if/else statements are called only once:
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
break;
case GST_MESSAGE_WARNING:
break;
case GST_MESSAGE_INFO:
break;
case GST_MESSAGE_EOS:
break;
case GST_MESSAGE_BUFFERING:
break;
case GST_MESSAGE_STATE_CHANGED: {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state,
&new_state, &pending_state);
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (__YOUR_PIPELINE_POINTER__)) {
// your code here
}
}
break;
}
// DON'T FORGET TO RETURN
return GST_BUS_DROP;
Hope, that helps ;-)

Related

my code print error even the input is correct

This is origin code
if (!isNullOrEmpty(configTypeBuilder.destinationField, RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH)) {
if (ruleAttributes.firstOrNull { ruleAttribute -> ruleAttribute == destinationField } == null) {
addValidationError(RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH, configTypeBuilder.destinationField, NOT_EXIST_CONSTRAINT)
}
}
I modify the code, just add the invalid value to a list, and then print them, but now when I enter valid destinationField after invalid destinationField, it will still show the error message, I don't know what's going on
val invalidDestination = hashSetOf<String>()
if (!isNullOrEmpty(configTypeBuilder.destinationField, RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH)) {
for (destinationField in destinationFieldList) {
if (!ruleAttributes.contains(destinationField)) {
invalidDestination.add(destinationField)
}
}
if (invalidDestination.size > 0) {
addValidationError(
"$RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH $NOT_EXIST_CONSTRAINT",
DESTINATION,
"$ADD_TAX_ENGINE_ATTRIBUTE_FIELDS $invalidDestination"
)
}
}
If your goal is to show error message only if there are no valid destinations, you need to add one more condition to your if statement. If not please clarify your question and post the whole function
Condition example:
var foundValid = false
for (destinationField in destinationFieldList) {
if (!ruleAttributes.contains(destinationField)) {
invalidDestination.add(destinationField)
}else {
foundValid = true
break //if you need invalidDestination list for later remove this break
}
}
if (invalidDestination.size > 0 && !foundValid) {
...
}

MBED BLE Payload values

I am working on a BLE Scanner.Basically I am looking for an iBeacon device with 0x4c type and a payload size of 30. However when i run this mbed crashes after spitting out few print lines. This code is very hit and miss.
it is getting an index out of bound error(understandably). How do I catch the error and skip it?
void Scanner::onAdvertisingReport(const AdvertisingReportEvent &event)
{
printf("Looking for Devices\r\n");
AdvertisingDataParser adv_data(event.getPayload());
while(adv_data.hasNext())
{
if (event.getPayload().size() == 30 and event.getPayload()[5] == 0x4c)
{
beacon_found = true;
while(beacon_found)
{
printf("Found Beacon!\r\n");
::print_address(event.getPeerAddress());
printf("RSSI : %d\r\n",event.getRssi());
printf("PL: %d\r\n",event.getPayload().size());
printf("Major Value: %d\r\n",event.getPayload()[26]);
printf("Minor Value: %d\r\n",event.getPayload()[27]);
break;
}
beacon_found = false;
break;
}
else
{
printf("Couldnt find beacon!\r\n");
break;
}
}
adv_data.next();
}
Error:
Error Status: 0x80FF0140 code 324 module 255
Assertion failed: 0 <= index && index < _size in Span.h

How to make a flag counter with react-native-beacons-manager

Scenario
Our app aims to detect beacons placed inside the restaurants our app
uses react-native-beacons-manager
When our app detects a beacon, I have developed a cloud function that accepts the beacon's major key and use it to query data of that restaurant from my database
The Cloud function then sends a push notification on the user about the restaurant details.
The Problem
The way I detect the beacons is not stable. this is my flow. I created a function located at
this.beaconsDidRangeEvent = Beacons.BeaconsEventEmitter.addListener(
//function-here
);
I can receive the beacons information like uuid, major and minor key and proximity (immediate, near, far, unknown) . Now inside that function I use the major key to determine the individuality of each beacons. Now, I've made a condition like this:
let beaconArr = data.beacons;
console.log(beaconArr);
console.log(count);
if (beaconArr.length > 0) {
console.log("beacons detected!");
let major = data.beacons[0].major;
let prox = data.beacons[0].proximity;
if ((prox === "near" || prox === "far") && beaconFlag === false && count === 0) {
console.log("beacon Action");
this.props.beaconAction(major);
this.props.createCheckInHistory(user.uid);
beaconFlag = true;
count++;
} else {
console.log("counter turned to 1!");
console.log(data);
beaconFlag = true;
}
} else {
console.log("no beacons detected!");
count = 0;
beaconFlag = false;
}
Expected Result
I expect that the functions inside the condition is true will only fire once.
Actual Result
Sometimes, its ok sometimes its not. even if im still at the range of the beacon, suddenly the beacon's array got 0. Then suddenly i'll receive a push notification again and again.
componentDidMount() Code
componentDidMount() {
this.props.selectedIcon('map');
firebase
.messaging()
.getInitialNotification()
.then(notification => {
console.log("Notification which opened the app: ", notification);
});
const user = firebase.auth().currentUser;
let count = 0;
let beaconFlag = false;
// will be set as a reference to "regionDidEnter" event:
this.beaconsDidRangeEvent = Beacons.BeaconsEventEmitter.addListener(
"beaconsDidRange",
_.throttle(data => {
let beaconArr = data.beacons;
console.log(beaconArr);
console.log(count);
if (beaconArr.length > 0) {
console.log("beacons detected!");
let major = data.beacons[0].major;
let prox = data.beacons[0].proximity;
if ((prox === "near" || prox === "far") && beaconFlag === false && count === 0) {
console.log("beacon Action");
this.props.beaconAction(major);
this.props.createCheckInHistory(user.uid);
beaconFlag = true;
count++;
} else {
console.log("counter turned to 1!");
console.log(data);
beaconFlag = true;
}
} else {
console.log("no beacons detected!");
count = 0;
beaconFlag = false;
}
}, 3000)
);
// monitoring events
this.regionDidEnterEvent = Beacons.BeaconsEventEmitter.addListener(
"regionDidEnter",
data => {
console.log("monitoring - regionDidEnter data: ", data);
}
);
// Monitoring: Listen for device leaving the defined region
this.regionDidExitEvent = Beacons.BeaconsEventEmitter.addListener(
"regionDidExit",
data => {
console.log("monitoring - regionDidExit data: ", data);
}
);
}
This is a common problem when ranging in beacon apps. Sometimes the detected beacons will briefly drop out then come back again. This can be solved by a software filter where you keep track of all beacons you have recently seen, and only perform an operation of it has not happened recently. In your case, you may use the major as the key to the index into the filter object.
// scope this globally
var minimumRetriggerMillis = 3600 * 1000; // 1hr
var recentTriggers = {};
// Before executing your trigger action:
var now = new Date().getTime();
if (recentTriggers[minor] == null || now-recentTriggers[minor] > minimumRetriggerMillis) {
recentTriggers[minor] = now;
// TODO: execute trigger logic here
}

check the status of the app moving or stationary

i want track my app status, i.e app is moving or stationary, I am using this module for location
https://github.com/mauron85/react-native-background-geolocation
for check the status of location i used this function
BackgroundGeolocation.on('stationary', (stationaryLocation) => {
console.log("stationaryLocation:"+JSON.stringify(stationaryLocation))
});
but it is not showing any response when i am stationary, can any one give me suggestion that how to resolve this.
Any help much appreciated.
Instead of using GeoLocation, you can use CMMotionActivityManager to track this.
public func getCurrentActivity(onRun:#escaping (_ activity: String?) -> Void) {
if(CMMotionActivityManager.isActivityAvailable()){
let mainQ = OperationQueue.main
self.activityManager?.startActivityUpdates(to: mainQ, withHandler: { (data: CMMotionActivity!) -> Void in
DispatchQueue.main.async(execute: {
var action = ""
if(data.stationary == true){
action = "Stationary"
} else if (data.walking == true){
action = "Walking"
} else if (data.running == true){
action = "Running"
} else if (data.automotive == true){
action = "Automotive"
} else if (data.cycling == true){
action = "cycling"
} else {
action = "Stationary"
}
onRun(action)
})
})
}
}

How to shorter code for weather api?

How could I shorter this part of the code and instead of putting all options append weather icons for all possible situations?
if (desc == "clear sky")
{
$('div.clear').removeClass('hide');
} else if (desc == "broken clouds")
{
$('div.cloudy').removeClass('hide');
}
else if (desc == "few clouds")
{
$('div.cloudy').removeClass('hide');
}
and so on...
else {
$('#desc').text("now it's ");
}
You can use a switch/case statement which would look like this
switch(desc)
{
case "clear sky":
$('div.clear').removeClass('hide');
break;
case "broken clouds":
$('div.cloudy').removeClass('hide');
break;
case "few clouds":
$('div.cloudy').removeClass('hide');
break;
case default:
$('#desc').text("now it's ");
break;
}
An other option would be to make a dictionary where the key is the case and the value is a function to execute.