I am working on content migration application. I have to migrate contacts, calendars, media from Blackberry device to Android device. Contacts and Calendars I have done.
I used below snip of code for Contacts
ContactService contactService;
ContactListFilters filters;
filters.setLimit(0);
QList<Contact> contactList = contactService.contacts(filters);
And below for Calendars
CalendarService calendarService;
EventSearchParameters searchParams;
searchParams.setStart(QDateTime(QDate(1918, 01, 01), QTime(00,00,00)));
searchParams.setEnd(QDateTime(QDate(2118, 12, 31), QTime(00,00,00)));
QList<CalendarEvent> eventList = calendarService.events(searchParams);
Its working fine.
Now, I have to lookup media in device i.e get media path based on type
say all Image, all Audio and all Video present in device.
Then with those path have to create a output stream and send it to
destination.
I've heard you can query the media SQL database available on every device, but I've never done it myself so I can't help on that one. The db file is located at /db/mmlibrary.db for media files stored on device and at /db/mmlibrary_SD.db for media files stored on SD card.
Otherwise, you can recursively navigate through the device and keep a global list of file paths. Note that doing so can take a long time, for my personal device it took 25 seconds to recursively go through all folders and find 186 audio files, 5127 picture files and 28 video files. You might want to execute this code in a separate thread to avoid blocking UI.
#include "applicationui.hpp"
#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <QFileInfo>
#include <QDir>
using namespace bb::cascades;
const QStringList audioFileExtensions = QStringList() << "mp3" << "wav";
const QStringList pictureFileExtensions = QStringList() << "bmp" << "gif" << "ico" << "jpg" << "jpeg" << "png" << "tiff";
const QStringList videoFileExtensions = QStringList() << "avi" << "mkv" << "mp4" << "mpeg";
ApplicationUI::ApplicationUI() :
QObject()
{
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("_app", this);
AbstractPane *root = qml->createRootObject<AbstractPane>();
Application::instance()->setScene(root);
}
//Declared as public Q_INVOKABLE in hpp
void ApplicationUI::findMediaFiles(QString parentFolder) {
QDateTime start = QDateTime::currentDateTime();
qDebug() << "findMediaFiles() started in" << parentFolder;
//Those 3 QStringList are declared as private variables in hpp
audioFilePaths.clear();
pictureFilePaths.clear();
videoFilePaths.clear();
if (parentFolder.isEmpty()) {
parentFolder = QString(getenv("PERIMETER_HOME")) + "/shared";
}
findMediaFilesRecursively(parentFolder);
qDebug() << audioFilePaths.size() << audioFilePaths;
qDebug() << pictureFilePaths.size() << pictureFilePaths;
qDebug() << videoFilePaths.size() << videoFilePaths;
qDebug() << "Took" << start.secsTo(QDateTime::currentDateTime()) << "seconds";
}
//Declared as private in hpp
void ApplicationUI::findMediaFilesRecursively(QString parentFolder) {
QDir dir(parentFolder);
dir.setFilter(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::NoSymLinks);
dir.setSorting(QDir::DirsFirst);
QFileInfoList fileInfoList = dir.entryInfoList();
foreach(QFileInfo fileInfo, fileInfoList) {
if (fileInfo.isDir()) {
findMediaFilesRecursively(fileInfo.absoluteFilePath());
continue;
}
QString extension = fileInfo.fileName().split(".").last();
if (audioFileExtensions.contains(extension, Qt::CaseInsensitive)) {
audioFilePaths.append(fileInfo.absoluteFilePath());
}
else if (pictureFileExtensions.contains(extension, Qt::CaseInsensitive)) {
pictureFilePaths.append(fileInfo.absoluteFilePath());
}
else if (videoFileExtensions.contains(extension, Qt::CaseInsensitive)) {
videoFilePaths.append(fileInfo.absoluteFilePath());
}
}
}
Related
I'm developing a Qt app which need to read data from weight scale model and can't quite understand how exactly the Bluetooth Low Energy works and how to implement it in Qt.
I have a UC-352BLE weight scale which uses BLE to send data. What I want to achieve is this:
After initial pairing the scale with my Raspberry Pi on which my app is running, when the scale sends data (it does it automatically when you take a measurement), my app receive it. For example I have a blood pressure monitor which uses normal Bluetooth and here it's easy. In my app, I create a QBluetoothServer and call its listen() method. Then when the (already paired) device sends a measurement, it connects with my app automatically, then I create QBluetoothSocket and read the data. But with the scale and it's BLE it seems that you can't do it that way. I tried to follow the Qt documentation on this and right now I just have to manually press the button which connects to the scale when it's sending the data. And every time it connects to the device it discovers it's characteristics and services etc. Don't know if I can do it so the app automatically receives a connection and reads a data when the scale sends a measurement. And even when I try to connects like that sometimes it connects and sometimes don't (I get Unknown error form QLowEnergyController::Error when connecting). Here is what I already have:
Bletest::Bletest(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::Bletest)
{
ui->setupUi(this);
if (localDevice.isValid()) {
localDevice.powerOn();
localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
connect(&localDevice, &QBluetoothLocalDevice::deviceConnected, this, &Bletest::deviceConnected);
connect(&localDevice, &QBluetoothLocalDevice::deviceDisconnected, this, &Bletest::deviceDisconnected);
connect(&localDevice, &QBluetoothLocalDevice::pairingFinished, this, &Bletest::pairingFinished);
}
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &Bletest::addDevice);
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &Bletest::scanFinished);
connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &Bletest::scanFinished);
discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
}
Bletest::~Bletest()
{
delete ui;
}
// Local device slots
void Bletest::deviceConnected(const QBluetoothAddress &address)
{
qDebug() << address.toString() << " connected";
}
void Bletest::deviceDisconnected(const QBluetoothAddress &address)
{
qDebug() << address.toString() << " disconnected";
}
void Bletest::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)
{
}
// Agent slots
void Bletest::addDevice(const QBluetoothDeviceInfo &device)
{
if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
if (device.name().contains("352")) {
bleDevice = device;
qDebug() << "Found: " + device.name() + "\t" + device.address().toString();
}
}
}
void Bletest::scanFinished()
{
qDebug() << "Devices scan finished";
}
///////////
void Bletest::on_connectButton_clicked()
{
controller = QLowEnergyController::createCentral(bleDevice, this);
connect(controller, &QLowEnergyController::serviceDiscovered, this, &Bletest::serviceDiscovered);
connect(controller, &QLowEnergyController::discoveryFinished, this, &Bletest::serviceScanFinished);
connect(controller, static_cast<void (QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error),
this, [this](QLowEnergyController::Error error) {
qDebug() << "Cannot connect to device: " + QString::number(error);
});
connect(controller, &QLowEnergyController::connected, this, [this]() {
qDebug() << "Connected to device";
controller->discoverServices();
});
connect(controller, &QLowEnergyController::disconnected, this, [this]() {
qDebug() << "Disconnected";
});
controller->connectToDevice();
}
// Controller slots
void Bletest::serviceDiscovered(const QBluetoothUuid &gatt)
{
qDebug() << "Service discovered: " << gatt.toString();
if (gatt.toString().contains("0000181d-0000-1000-8000-00805f9b34fb")) {
service = controller->createServiceObject(QBluetoothUuid(QBluetoothUuid::WeightScale));
if (service) {
qDebug() << "Found weight scale service";
connect(service, &QLowEnergyService::stateChanged, this, &Bletest::serviceStateChanged);
connect(service, &QLowEnergyService::characteristicChanged, this, &Bletest::updateWeight);
connect(service, &QLowEnergyService::characteristicRead, this, &Bletest::updateWeight);
service->discoverDetails();
}
}
}
void Bletest::serviceScanFinished()
{
qDebug() << "Service scan finished";
}
////////////////////////////
// Service slots
void Bletest::serviceStateChanged(QLowEnergyService::ServiceState newState)
{
if (controller->state() == QLowEnergyController::UnconnectedState)
return;
if (newState == QLowEnergyService::DiscoveringServices) {
qDebug() << "Discovering services state";
} else if (QLowEnergyService::ServiceDiscovered) {
qDebug() << "Service discovered.";
const QLowEnergyCharacteristic weightChar = service->characteristic(QBluetoothUuid(QBluetoothUuid::WeightMeasurement));
if (!weightChar.isValid()) {
qDebug() << "Weight data not found";
return;
}
qDebug() << "Weight data found";
//service->readCharacteristic(weightChar);
desc = weightChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
if (desc.isValid()) {
qDebug() << "Writing descriptor";
service->writeDescriptor(desc, QByteArray::fromHex("0100"));
}
}
}
void Bletest::updateWeight(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
qDebug() << "Updating weight";
if (c.uuid() != QBluetoothUuid(QBluetoothUuid::WeightMeasurement))
return;
double weight = qFromLittleEndian<qint16>(value.mid(1, 2).data()) * RESOLUTION;
qDebug() << "New weight: " << value.mid(1, 2);
qDebug() << "New weight: " + QString::number(weight, 'f', 2);
}
///////////////////////////
Can someone point me in the right direction with this? Is is even possible with BLE to automatically connects to my app and receive data?
Thanks.
I'm not very good at character devices, so I need your help. A have a char device(let's call it /dev/my_light) which is a light sensor. I have to read the data from this file and transform it to the brightness value and then pass it to the brightness manager that changes the brightness of my screen. The problem is that when I read the value for some period of time I get old values from the file.I assume there is a buffer(again not sure how character devices exactly work). Whereas when I use cat /dev/my_light I see new data! Is it possible to get rid off the buffer and read new values that were written to the file just right now. Here is my code in Qt:
void MySensor::updateMySensor()
{
Packet packet;
packet.startByte = 0;
packet.mantissa = 0;
packet.exp = 0;
d->device = ::open(d->path.toStdString().c_str(), O_RDONLY);
if (d->device == -1)
{
qDebug() << Q_FUNC_INFO << "can't open the sensor";
return;
}
ssize_t size = ::read(d->device, &packet, sizeof(packet));
close(d->device);
if (size == -1)
{
qDebug() << errno;
return;
}
packet.exp &= 0x0F;
float illumination = pow(2, packet.exp) * packet.mantissa * 0.045;
if(d->singleShot) emit lightSensorIsRunning(true);
emit illuminationRead(illumination);
}
The mySensor function is called every second. I tried to call it each 200 msec but it didn't help. The value of illumination stays old for about 7 seconds(!) whereas the value that I get from cat is new just immediately.
Thank you in advance!
I can't test with your specific device, however, I'm using the keyboard as a read only device.
The program attempts to connect to keyboard and read all keys pressed inside and outside the window. It's a broad solution you'll have to adapt to meet your demands.
Note that I'm opening the file with O_RDONLY | O_NONBLOCK which means open in read only mode and no wait for the event be triggered(some notifier needed to know when data is ready!) respectively.
You'll need super user privilege to run this example!
#include <QtCore>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const char *device_name = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
int descriptor = open(device_name, O_RDONLY | O_NONBLOCK);
if (descriptor < 0)
{
qDebug() << "Error" << strerror(errno);
return a.exec();
}
QFile device;
if (!device.open(descriptor, QFile::ReadOnly))
{
qDebug() << "Error" << qPrintable(device.errorString());
return a.exec();
}
QSocketNotifier notifier(device.handle(), QSocketNotifier::Read);
QObject::connect(¬ifier, &QSocketNotifier::activated, ¬ifier, [&](int socket){
Q_UNUSED(socket)
struct input_event ev;
QByteArray data = device.readAll();
qDebug() << "Event caught:"
<< "\n\nDATA SIZE" << data.size()
<< "\nSTRUCT COUNT" << data.size() / int(sizeof(input_event))
<< "\nSTRUCT SIZE" << sizeof(input_event);
qDebug() << ""; //New line
while (data.size() >= int(sizeof(input_event)))
{
memcpy(&ev, data.data(), sizeof(input_event));
data.remove(0, int(sizeof(input_event)));
qDebug() << "TYPE" << ev.type << "CODE" << ev.code << "VALUE" << ev.value << "TIME" << ev.time.tv_sec;
}
qDebug() << ""; //New line
});
return a.exec();
}
I want to use pre-made files instead of live capture in the following program to track the person.
what is realsense SDK API used to load pre-made files and catch the frame by frame?
Is it possible to use to detect/track person any general video/image files which captured using any other camera's ?
Example Program:
Example Source Link
Source
#include <thread>
#include <iostream>
#include <signal.h>
#include "version.h"
#include "pt_utils.hpp"
#include "pt_console_display.hpp"
#include "pt_web_display.hpp"
#include "or_console_display.hpp"
#include "or_web_display.hpp"
using namespace std;
using namespace rs::core;
using namespace rs::object_recognition;
// Version number of the samples
extern constexpr auto rs_sample_version = concat("VERSION: ",RS_SAMPLE_VERSION_STR);
// Doing the OR processing for a frame can take longer than the frame interval, so we
// keep track of whether or not we are still processing the last frame.
bool is_or_processing_frame = false;
unique_ptr<web_display::pt_web_display> pt_web_view;
unique_ptr<web_display::or_web_display> or_web_view;
unique_ptr<console_display::pt_console_display> pt_console_view;
unique_ptr<console_display::or_console_display> or_console_view;
void processing_OR(correlated_sample_set or_sample_set, or_video_module_impl* impl, or_data_interface* or_data,
or_configuration_interface* or_configuration)
{
rs::core::status st;
// Declare data structure and size for results
rs::object_recognition::localization_data* localization_data = nullptr;
//Run object localization processing
st = impl->process_sample_set(or_sample_set);
if (st != rs::core::status_no_error)
{
is_or_processing_frame = false;
return;
}
// Retrieve recognition data from the or_data object
int array_size = 0;
st = or_data->query_localization_result(&localization_data, array_size);
if (st != rs::core::status_no_error)
{
is_or_processing_frame = false;
return;
}
//Send OR data to ui
if (localization_data && array_size != 0)
{
or_console_view->on_object_localization_data(localization_data, array_size, or_configuration);
or_web_view->on_object_localization_data(localization_data, array_size, or_configuration);
}
is_or_processing_frame = false;
}
int main(int argc,char* argv[])
{
rs::core::status st;
pt_utils pt_utils;
rs::core::image_info colorInfo,depthInfo;
rs::core::video_module_interface::actual_module_config actualModuleConfig;
rs::person_tracking::person_tracking_video_module_interface* ptModule = nullptr;
rs::object_recognition::or_video_module_impl impl;
rs::object_recognition::or_data_interface* or_data = nullptr;
rs::object_recognition::or_configuration_interface* or_configuration = nullptr;
cout << endl << "Initializing Camera, Object Recognition and Person Tracking modules" << endl;
if(pt_utils.init_camera(colorInfo,depthInfo,actualModuleConfig,impl,&or_data,&or_configuration) != rs::core::status_no_error)
{
cerr << "Error: Device is null." << endl << "Please connect a RealSense device and restart the application" << endl;
return -1;
}
pt_utils.init_person_tracking(&ptModule);
//Person Tracking Configuration. Set tracking mode to 0
ptModule->QueryConfiguration()->QueryTracking()->Enable();
ptModule->QueryConfiguration()->QueryTracking()->SetTrackingMode((Intel::RealSense::PersonTracking::PersonTrackingConfiguration::TrackingConfiguration::TrackingMode)0);
if(ptModule->set_module_config(actualModuleConfig) != rs::core::status_no_error)
{
cerr<<"error : failed to set the enabled module configuration" << endl;
return -1;
}
//Object Recognition Configuration
//Set mode to localization
or_configuration->set_recognition_mode(rs::object_recognition::recognition_mode::LOCALIZATION);
//Set the localization mechnizm to use CNN
or_configuration->set_localization_mechanism(rs::object_recognition::localization_mechanism::CNN);
//Ignore all objects under 0.7 probabilty (confidence)
or_configuration->set_recognition_confidence(0.7);
//Enabling object center feature
or_configuration->enable_object_center_estimation(true);
st = or_configuration->apply_changes();
if (st != rs::core::status_no_error)
return st;
//Launch GUI
string sample_name = argv[0];
// Create console view
pt_console_view = move(console_display::make_console_pt_display());
or_console_view = move(console_display::make_console_or_display());
// Create and start remote(Web) view
or_web_view = move(web_display::make_or_web_display(sample_name, 8000, true));
pt_web_view = move(web_display::make_pt_web_display(sample_name, 8000, true));
cout << endl << "-------- Press Esc key to exit --------" << endl << endl;
while (!pt_utils.user_request_exit())
{
//Get next frame
rs::core::correlated_sample_set* sample_set = pt_utils.get_sample_set(colorInfo,depthInfo);
rs::core::correlated_sample_set* sample_set_pt = pt_utils.get_sample_set(colorInfo,depthInfo);
//Increment reference count of images at sample set
for (int i = 0; i < static_cast<uint8_t>(rs::core::stream_type::max); ++i)
{
if (sample_set_pt->images[i] != nullptr)
{
sample_set_pt->images[i]->add_ref();
}
}
//Draw Color frames
auto colorImage = (*sample_set)[rs::core::stream_type::color];
pt_web_view->on_rgb_frame(10, colorImage->query_info().width, colorImage->query_info().height, colorImage->query_data());
//Run OR in a separate thread. Update GUI with the result
if (!is_or_processing_frame) // If we aren't already processing or for a frame:
{
is_or_processing_frame = true;
std::thread recognition_thread(processing_OR, *sample_set,
&impl, or_data, or_configuration);
recognition_thread.detach();
}
//Run Person Tracking
if (ptModule->process_sample_set(*sample_set_pt) != rs::core::status_no_error)
{
cerr << "error : failed to process sample" << endl;
continue;
}
//Update GUI with PT result
pt_console_view->on_person_info_update(ptModule);
pt_web_view->on_PT_tracking_update(ptModule);
}
pt_utils.stop_camera();
actualModuleConfig.projection->release();
return 0;
}
After installing the Realsense SKD, check the realsense_playback_device_sample for how to load the RSSDK capture file.
The short answer is not really. Beside the images that are captured from the other camera, you also need to supply the camera intrinsic and extrinsic settings in order to calculate the depth of and object and call the person tracking module.
I want to use QSettings to save my window's dimensions so I came up with these two functions to save & load the settings:
void MainWindow::loadSettings()
{
settings = new QSettings("Nothing","KTerminal");
int MainWidth = settings->value("MainWidth").toInt();
int MainHeight = settings->value("MainHeight").toInt();
std::cout << "loadSettings " << MainWidth << "x" << MainHeight << std::endl;
std::cout << "file: " << settings->fileName().toLatin1().data() << std::endl;
if (MainWidth && MainHeight)
this->resize(MainWidth,MainHeight);
else
this->resize(1300, 840);
}
void MainWindow::saveSettings()
{
int MainHeight = this->size().height();
int MainWidth = this->size().width();
std::cout << "file: " << settings->fileName().toLatin1().data() << std::endl;
std::cout << "saveSettings " << MainWidth << "x" << MainHeight << std::endl;
settings->setValue("MainHeight",MainHeight);
settings->setValue("MainWidth",MainWidth);
}
Now, I can see the demensions being extracted in saveSettings as expected but no file gets created and hence loadSettings will always load 0 only. Why is this?
QSettings isn't normally instantiated on the heap. To achieve the desired effect that you are looking for, follow the Application Example and how it is shown in the QSettings documentation.
void MainWindow::readSettings()
{
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
if (geometry.isEmpty()) {
const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
move((availableGeometry.width() - width()) / 2,
(availableGeometry.height() - height()) / 2);
} else {
restoreGeometry(geometry);
}
}
void MainWindow::writeSettings()
{
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
settings.setValue("geometry", saveGeometry());
}
Also note the use of saveGeometry() and restoreGeometry(). Other similarly useful functions for QWidget based GUIs are saveState() and restoreState() (not shown in the above example).
I strongly recommend the zero parameter constructor of QSettings, and to setup the defaults in your main.cpp, like so:
QSettings::setDefaultFormat(QSettings::IniFormat); // personal preference
qApp->setOrganizationName("Moose Soft");
qApp->setApplicationName("Facturo-Pro");
Then when you want to use QSettings in any part of your application, you simply do:
QSettings settings;
settings.setValue("Category/name", value);
// or
QString name_str = settings.value("Category/name", default_value).toString();
QSettings in general is highly optimized, and works really well.
Hope that helps.
Some other places where I've talked up usage of QSettings:
Using QSettings in a global static class
https://stackoverflow.com/a/14365937/999943
I'm using the wonderful [QtAV](https://github.com/wang-bin/QtAV/) package to perform video decoding. What I want to achieve is to obtain a thumbnail for a video. Here is what I have done so far.
bool saveThumb( QString videoFile ) {
AVDemuxer *demux = new AVDemuxer();
demux->setSeekUnit( SeekByFrame );
demux->setSeekType( KeyFrameSeek );
VideoDecoder *vdec = VideoDecoder::create( VideoDecoderId_FFmpeg );
demux->setMedia( videoFile );
qDebug() << "Loading file:" << demux->load();
qDebug() << "Seeking to 50%" << demux->seek( 0.5 );
qDebug() << "Reading frame:" << demux->readFrame();
vdec->setCodecContext( demux->videoCodecContext() );
vdec->open();
Packet pkt = demux->packet();
qDebug() << "Packet valid:" << pkt.isValid();
qDebug() << "Decoding packet:" << vdec->decode( pkt );
VideoFrame frame = vdec->frame();
qDebug() << "Valid frame:" << frame.isValid();
QImage img = frame.toImage();
qDebug() << "Valid image:" << ( not img.isNull() );
bool saved = img.save( videoFile + ".jpg" );
return saved;
}
My problem is that frame.isValid() always returns false, no matter to where I seek, or which video I play. All the checks above return true.
I would like to add that if I use AVPlayer and play the video, the video renders properly, however there is no audio playing.
Also I am able to capture snapshots using AVPlayer::videoCapture()->capture()
For the record, I have tried this using both Qt4 and Qt5
For getting thumbnails of videos you can simply use QtAV VideoFrameExtractor class like:
#include "QtAV/VideoFrameExtractor.h"
...
bool saveThumb(const QString& videoFile) {
auto extractor = new QtAV::VideoFrameExtractor;
connect(
extractor,
&QtAV::VideoFrameExtractor::frameExtracted,
extractor,
[this, extractor, videoFile](const QtAV::VideoFrame& frame) {
const auto& img = frame.toImage();
auto saved = img.save(videoFile + ".jpg" );
extractor->deleteLater();
});
connect(
extractor,
&QtAV::VideoFrameExtractor::error,
extractor,
[this, extractor](const QString& errorStr) {
qDebug() << errorStr;
extractor->deleteLater();
});
extractor->setAsync(true);
extractor->setSource(videoFile);
extractor->setPosition(1);
}