[DEV] update seek and better display
@ -64,11 +64,11 @@ namespace appl {
|
||||
}
|
||||
}
|
||||
// TODO : Remove this: Move if in the windows properties
|
||||
_context.setSize(vec2(800, 600));
|
||||
_context.setSize(vec2(400, 300));
|
||||
// eneble the search of the font in the system font path
|
||||
_context.getFontDefault().setUseExternal(true);
|
||||
// select font preference of der with a basic application size
|
||||
_context.getFontDefault().set("DejaVuSerif;FreeSerif;DejaVuSansMono", 19);
|
||||
_context.getFontDefault().set("DejaVuSerif;FreeSerif;DejaVuSansMono", 12);
|
||||
// set application widget:
|
||||
appl::widget::VideoDisplay::createManagerWidget(_context.getWidgetManager());
|
||||
appl::widget::ListViewer::createManagerWidget(_context.getWidgetManager());
|
||||
|
@ -210,6 +210,7 @@ int appl::MediaDecoder::decode_packet(int *_gotFrame, int _cached) {
|
||||
m_currentVideoTime = m_currentAudioTime;
|
||||
m_updateVideoTimeStampAfterSeek = false;
|
||||
m_seekApply = m_currentVideoTime; // => ready to display
|
||||
APPL_DEBUG("Update seek time: " << m_seekApply);
|
||||
}
|
||||
echrono::Duration packetTime(double(m_frame->pkt_pts) * double(m_videoDecoderContext->time_base.num) / double(m_videoDecoderContext->time_base.den));
|
||||
APPL_VERBOSE("video_frame " << (_cached?"(cached)":"")
|
||||
@ -250,7 +251,8 @@ int appl::MediaDecoder::decode_packet(int *_gotFrame, int _cached) {
|
||||
echrono::Duration packetTime(double(m_frame->pkt_pts) * double(m_audioDecoderContext->time_base.num) / double(m_audioDecoderContext->time_base.den));
|
||||
if (m_updateVideoTimeStampAfterSeek == true) {
|
||||
// seek specific usecase ==> drop frame to have fast display
|
||||
m_currentAudioTime = packetTime;
|
||||
//TODO : UNDERSTAND why : m_currentAudioTime = packetTime;
|
||||
APPL_DEBUG("Update audio time with packet time: " << packetTime);
|
||||
} else {
|
||||
APPL_VERBOSE("audio_frame " << (_cached?"(cached)":"")
|
||||
<< " n=" << m_audioFrameCount
|
||||
@ -386,6 +388,17 @@ void appl::MediaDecoder::init(ememory::SharedPtr<ClientProperty> _property, uint
|
||||
int appl::MediaDecoder::readFunc(uint8_t* _buf, int _bufSize) {
|
||||
APPL_INFO("call read ... " << m_remote->m_bufferReadPosition << " size=" << _bufSize);
|
||||
// check if enought data:
|
||||
m_remote->startStream();
|
||||
if (m_remote->m_bufferReadPosition >= m_remote->m_buffer.size()) {
|
||||
return 0;
|
||||
}
|
||||
while(m_remote->sizeReadable() == 0) {
|
||||
APPL_WARNING(" -------- waiting data --------- ");// << m_remote->sizeReadable());
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
if (m_stopRequested == true) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int64_t readableSize = m_remote->sizeReadable();
|
||||
if (_bufSize > readableSize) {
|
||||
_bufSize = readableSize;
|
||||
@ -394,12 +407,12 @@ int appl::MediaDecoder::readFunc(uint8_t* _buf, int _bufSize) {
|
||||
// No data in the buffer
|
||||
return 0;
|
||||
}
|
||||
// Real Load of the data:
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_remote->m_mutex);
|
||||
memcpy(_buf, &m_remote->m_buffer[m_remote->m_bufferReadPosition], _bufSize);
|
||||
m_remote->m_bufferReadPosition += _bufSize;
|
||||
}
|
||||
m_remote->startStream();
|
||||
m_remote->checkIfWeNeedMoreDataFromNetwork();
|
||||
return _bufSize;
|
||||
}
|
||||
@ -457,11 +470,6 @@ int64_t appl::MediaDecoder::seekFunc(int64_t _offset, int _whence) {
|
||||
m_remote->m_bufferReadPosition = m_remote->m_buffer.size()-1;
|
||||
}
|
||||
if (lastPosition != m_remote->m_bufferReadPosition) {
|
||||
{
|
||||
// Force the get of new data ==> this is bad TODO : Update this when possible
|
||||
std::unique_lock<std::mutex> lock(m_remote->m_mutex);
|
||||
m_remote->m_callInProgress = false;
|
||||
}
|
||||
m_remote->checkIfWeNeedMoreDataFromNetwork();
|
||||
}
|
||||
return m_remote->m_bufferReadPosition;
|
||||
@ -469,7 +477,7 @@ int64_t appl::MediaDecoder::seekFunc(int64_t _offset, int _whence) {
|
||||
|
||||
bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_t _positionRequest) {
|
||||
#ifdef DEBUG
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
#endif
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
@ -481,7 +489,7 @@ bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_
|
||||
}
|
||||
// TODO : Check buffer size ...
|
||||
zeus::Raw buffer = _fut.get();
|
||||
APPL_INFO(" ==> receive DATA : " << _positionRequest << " size=" << buffer.size());
|
||||
APPL_DEBUG(" ==> receive DATA : " << _positionRequest << " size=" << buffer.size());
|
||||
// copy data
|
||||
memcpy(&m_buffer[_positionRequest], buffer.data(), buffer.size());
|
||||
// Update the buffer data and positionning
|
||||
@ -508,13 +516,14 @@ bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_
|
||||
it2->first = _positionRequest;
|
||||
find = true;
|
||||
break;
|
||||
} else {
|
||||
}/* else {
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
++it;
|
||||
}
|
||||
if (find == false) {
|
||||
APPL_ERROR("insert new element in the list of values");
|
||||
m_bufferFillSection.insert(it, std::pair<uint32_t,uint32_t>(_positionRequest, _positionRequest + buffer.size()));
|
||||
}
|
||||
}
|
||||
@ -524,19 +533,22 @@ bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_
|
||||
|
||||
|
||||
appl::StreamBuffering::StreamBuffering() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_callInProgress = false;
|
||||
m_stopRequested = false;
|
||||
m_mediaId = 0;
|
||||
m_bufferReadPosition = 0;
|
||||
}
|
||||
void appl::StreamBuffering::stopStream() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_stopRequested = true;
|
||||
}
|
||||
void appl::StreamBuffering::startStream() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_stopRequested = false;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add requested section ...
|
||||
void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
// check if enought data:
|
||||
@ -549,26 +561,15 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
|
||||
}
|
||||
int32_t preDownloadBufferSlot = BUFFER_SIZE_GET_SLOT*3;
|
||||
// When file is < 200Mo ==> just download all...
|
||||
#if 1
|
||||
if (m_buffer.size() < 300*1024*1024) {
|
||||
preDownloadBufferSlot = m_buffer.size()+10;
|
||||
}
|
||||
APPL_VERBOSE("Request DATA ...");
|
||||
#endif
|
||||
APPL_DEBUG("Request DATA ... section number = " << m_bufferFillSection.size());
|
||||
auto it = m_bufferFillSection.begin();
|
||||
if (it == m_bufferFillSection.end()) {
|
||||
// no data in the buffer...
|
||||
//Get some
|
||||
// start with loading of 1 Mo
|
||||
APPL_VERBOSE("Request DATA : " << 0 << " size=" << BUFFER_SIZE_GET_SLOT);
|
||||
auto futData = m_fileHandle.getPart(0, BUFFER_SIZE_GET_SLOT);
|
||||
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
|
||||
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
|
||||
return localShared->addDataCallback(_fut, 0);
|
||||
});
|
||||
m_callInProgress = true;
|
||||
return;
|
||||
}
|
||||
while (it != m_bufferFillSection.end()) {
|
||||
APPL_VERBOSE("Check : " << it->first << " -> " << it->second << " read-pos=" << m_bufferReadPosition);
|
||||
APPL_DEBUG("Check : " << it->first << " -> " << it->second << " read-pos=" << m_bufferReadPosition);
|
||||
if ( m_bufferReadPosition >= it->first
|
||||
&& m_bufferReadPosition < it->second) {
|
||||
find = true;
|
||||
@ -580,15 +581,22 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
|
||||
if (it->second - m_bufferReadPosition < preDownloadBufferSlot) {
|
||||
int32_t sizeRequest = BUFFER_SIZE_GET_SLOT;
|
||||
if (it->second + sizeRequest >= m_buffer.size()) {
|
||||
APPL_DEBUG("max area: " << it->second << "+" << sizeRequest << "=" << it->second + sizeRequest << " ->" << m_buffer.size());
|
||||
sizeRequest = m_buffer.size() - it->second;
|
||||
APPL_DEBUG(" -> sizeRequested=" << sizeRequest);
|
||||
}
|
||||
auto it2 = it;
|
||||
++it2;
|
||||
if ( it2 != m_bufferFillSection.end()
|
||||
&& it->second + sizeRequest >= it2->first) {
|
||||
APPL_DEBUG("empty area: " << it->second << " ->" << it2->first);
|
||||
sizeRequest = it2->first - it->second;
|
||||
APPL_DEBUG(" -> sizeRequested=" << sizeRequest);
|
||||
}
|
||||
APPL_VERBOSE("Request DATA : " << it->second << " size=" << sizeRequest);
|
||||
if (sizeRequest == 0) {
|
||||
return;
|
||||
}
|
||||
APPL_DEBUG("Request DATA: " << it->second << " size=" << sizeRequest);
|
||||
auto futData = m_fileHandle.getPart(it->second, it->second + sizeRequest);
|
||||
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
|
||||
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
|
||||
@ -603,7 +611,10 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
|
||||
if (m_bufferReadPosition + sizeRequest >= it->first) {
|
||||
sizeRequest = it->first - m_bufferReadPosition;
|
||||
}
|
||||
APPL_VERBOSE("Request DATA : " << m_bufferReadPosition << " size=" << sizeRequest);
|
||||
if (sizeRequest == 0) {
|
||||
return;
|
||||
}
|
||||
APPL_DEBUG("Request DATA : " << m_bufferReadPosition << " size=" << sizeRequest);
|
||||
auto futData = m_fileHandle.getPart(m_bufferReadPosition, m_bufferReadPosition+sizeRequest);
|
||||
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
|
||||
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
|
||||
@ -615,11 +626,21 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
|
||||
}
|
||||
++it;
|
||||
}
|
||||
APPL_VERBOSE("Request DATA : " << m_bufferReadPosition << " size=" << BUFFER_SIZE_GET_SLOT);
|
||||
auto futData = m_fileHandle.getPart(m_bufferReadPosition, m_bufferReadPosition + BUFFER_SIZE_GET_SLOT);
|
||||
int32_t sizeRequest = BUFFER_SIZE_GET_SLOT;
|
||||
if (m_bufferReadPosition + sizeRequest >= m_buffer.size()) {
|
||||
APPL_DEBUG("max area: " << m_bufferReadPosition << "+" << sizeRequest << "=" << m_bufferReadPosition + sizeRequest << " ->" << m_buffer.size());
|
||||
sizeRequest = m_buffer.size() - m_bufferReadPosition;
|
||||
APPL_DEBUG(" -> sizeRequested=" << sizeRequest);
|
||||
}
|
||||
if (sizeRequest == 0) {
|
||||
// nothing to request ...
|
||||
return;
|
||||
}
|
||||
APPL_DEBUG("Request DATA : " << m_bufferReadPosition << " size=" << sizeRequest);
|
||||
auto futData = m_fileHandle.getPart(m_bufferReadPosition, m_bufferReadPosition + sizeRequest);
|
||||
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
|
||||
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
|
||||
return localShared->addDataCallback(_fut, 0);
|
||||
return localShared->addDataCallback(_fut, m_bufferReadPosition);
|
||||
});
|
||||
m_callInProgress = true;
|
||||
if (find == false) {
|
||||
|
@ -72,9 +72,11 @@ namespace appl {
|
||||
bool addDataCallback(zeus::Future<zeus::Raw> _fut, int64_t _positionRequest);
|
||||
void checkIfWeNeedMoreDataFromNetwork();
|
||||
uint64_t getSize() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return m_buffer.size();
|
||||
}
|
||||
std::vector<std::pair<uint32_t,uint32_t>> getDownloadPart() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return m_bufferFillSection;
|
||||
}
|
||||
int32_t sizeReadable();
|
||||
@ -164,9 +166,9 @@ namespace appl {
|
||||
void flushMessage();
|
||||
|
||||
void stop() override;
|
||||
/* ***********************************************
|
||||
** Section temporary buffer
|
||||
***********************************************/
|
||||
/* ***********************************************
|
||||
** Section temporary buffer
|
||||
***********************************************/
|
||||
ememory::SharedPtr<appl::StreamBuffering> m_remote;
|
||||
public:
|
||||
// @brief INTERNAL read callback
|
||||
@ -184,7 +186,7 @@ namespace appl {
|
||||
std::vector<std::pair<uint32_t,uint32_t>> vals = m_remote->getDownloadPart();
|
||||
echrono::Duration totalTime = getDuration();
|
||||
float size = totalTime.toSeconds()/float(m_remote->getSize());
|
||||
APPL_ERROR(" duration in sec : " << totalTime << " => " << totalTime.toSeconds());
|
||||
//APPL_ERROR(" duration in sec : " << totalTime << " => " << totalTime.toSeconds());
|
||||
for (auto &it : vals) {
|
||||
out.push_back(std::pair<float,float>(float(it.first)*size, float(it.second)*size));
|
||||
}
|
||||
|
@ -219,12 +219,12 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
|
||||
std::u32string errorString = U"No element Availlable";
|
||||
|
||||
m_text.clear();
|
||||
// to know the size of one line :
|
||||
vec3 minSize = m_text.calculateSize(char32_t('A'));
|
||||
if (m_listElement.size() == 0) {
|
||||
int32_t paddingSize = 2;
|
||||
|
||||
vec2 tmpMax = propertyMaxSize->getPixel();
|
||||
// to know the size of one line :
|
||||
vec3 minSize = m_text.calculateSize(char32_t('A'));
|
||||
|
||||
/*
|
||||
if (tmpMax.x() <= 999999) {
|
||||
@ -276,7 +276,7 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
|
||||
// Here the real Display get a square in pixel of 2cm x 2cm:
|
||||
vec2 realPixelSize = gale::Dimension(vec2(3,3), gale::distance::centimeter).getPixel();
|
||||
// TODO : Understand Why this not work ...
|
||||
realPixelSize = vec2(150,150);
|
||||
realPixelSize = vec2(minSize.y()*4,minSize.y()*4+6); // add arbitrary 6 pixel ...
|
||||
// This will generate the number of element that can be displayed:
|
||||
int32_t verticalNumber = m_size.y() / realPixelSize.y() + 2; // +1 for the not entire view of element and +1 for the moving element view ...
|
||||
//verticalNumber = 10;
|
||||
@ -290,14 +290,19 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
|
||||
m_listDisplay.push_back(elem);
|
||||
}
|
||||
}
|
||||
int32_t offset = m_originScrooled.y() / realPixelSize.y();
|
||||
APPL_VERBOSE("origin scrolled : " << m_originScrooled << " nb Pixel/element = " << realPixelSize.y() << " offset=" << offset);
|
||||
for (size_t iii=0; iii<m_listDisplay.size(); ++iii) {
|
||||
auto elem = m_listDisplay[iii];
|
||||
if (elem != nullptr) {
|
||||
elem->m_idCurentElement = iii;
|
||||
if (iii < m_listElement.size()) {
|
||||
elem->m_property = m_listElement[iii];
|
||||
elem->m_idCurentElement = offset + iii;
|
||||
if (offset + iii < m_listElement.size()) {
|
||||
elem->m_property = m_listElement[offset + iii];
|
||||
} else {
|
||||
elem->m_property.reset();
|
||||
}
|
||||
switch(iii%6) {
|
||||
//switch(iii%6) {
|
||||
switch((offset + iii)%6) {
|
||||
case 0:
|
||||
elem->m_bgColor = etk::color::red;
|
||||
break;
|
||||
@ -324,9 +329,12 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
|
||||
APPL_ERROR("create nullptr");
|
||||
}
|
||||
}
|
||||
|
||||
//display only ofsetted element
|
||||
float realOffset = float(int32_t(m_originScrooled.y() / realPixelSize.y())) * realPixelSize.y();
|
||||
// Now we request display of the elements:
|
||||
vec2 elementSize = vec2(m_size.x(), int32_t(realPixelSize.y()));
|
||||
vec2 startPos = vec2(-m_originScrooled.x(), m_size.y()) - vec2(0, elementSize.y()-m_originScrooled.y());
|
||||
vec2 startPos = vec2(-m_originScrooled.x(), m_size.y()) - vec2(0, elementSize.y()-(m_originScrooled.y()-realOffset));
|
||||
for (auto &it : m_listDisplay) {
|
||||
if (it == nullptr) {
|
||||
startPos -= vec2(0, elementSize.y());
|
||||
@ -389,11 +397,13 @@ void appl::ElementDisplayed::generateDisplay(vec2 _startPos, vec2 _size) {
|
||||
m_text.reset();
|
||||
m_text.setDefaultColorFg(etk::color::black);
|
||||
vec3 minSize = m_text.calculateSize(char32_t('A'));
|
||||
vec2 originText = _startPos + vec2(_size.y()+10, _size.y()-minSize.y() - 10);
|
||||
float borderOffset = 4;
|
||||
vec2 originText = _startPos + vec2(_size.y()+borderOffset, _size.y()-minSize.y() - borderOffset);
|
||||
m_text.setPos(originText);
|
||||
//APPL_INFO("Regenerate display : " << tmpTextOrigin << " " << m_origin << " " << m_size);
|
||||
//APPL_VERBOSE("[" << getId() << "] {" << errorString << "} display at pos : " << tmpTextOrigin);
|
||||
m_text.setTextAlignement(originText.x(), originText.x()+_size.x()-_size.y(), ewol::compositing::alignLeft);
|
||||
m_text.setTextAlignement(originText.x(), originText.x()+_size.x()-_size.y(), ewol::compositing::alignDisable);
|
||||
// TODO: m_text.setClipping(originText, vec2(originText.x()+_size.x()-_size.y(), _size.y()));
|
||||
//m_text.setClipping(drawClippingPos, drawClippingSize);
|
||||
std::string textToDisplay = "<b>" + m_property->m_title + "</b><br/>";
|
||||
bool newLine = false;
|
||||
|
@ -44,7 +44,7 @@ void appl::widget::Player::init() {
|
||||
subBind(appl::widget::VideoDisplay, "[" + etk::to_string(getId()) + "]appl-player-display", signalDuration, sharedFromThis(), &appl::widget::Player::onCallbackDuration);
|
||||
|
||||
subBind(appl::widget::VideoDisplay, "[" + etk::to_string(getId()) + "]appl-player-display", signalFps, sharedFromThis(), &appl::widget::Player::onCallbackFPS);
|
||||
subBind(ewol::widget::Slider, "[" + etk::to_string(getId()) + "]appl-player-progress-bar", signalChange, sharedFromThis(), &appl::widget::Player::onCallbackSeekRequest);
|
||||
subBind(appl::widget::ProgressBar, "[" + etk::to_string(getId()) + "]appl-player-progress-bar", signalChange, sharedFromThis(), &appl::widget::Player::onCallbackSeekRequest);
|
||||
|
||||
m_display = ememory::dynamicPointerCast<appl::widget::VideoDisplay>(getSubObjectNamed("[" + etk::to_string(getId()) + "]appl-player-display"));
|
||||
m_progress = ememory::dynamicPointerCast<appl::widget::ProgressBar>(getSubObjectNamed("[" + etk::to_string(getId()) + "]appl-player-progress-bar"));
|
||||
@ -76,17 +76,48 @@ void appl::widget::Player::playStream(ememory::SharedPtr<appl::ClientProperty> _
|
||||
}
|
||||
|
||||
|
||||
static std::string timeToStaticString(const echrono::Duration& _time) {
|
||||
float sec = _time.toSeconds();
|
||||
int32_t millisecond = int32_t(sec*1000.0f)%999;
|
||||
int32_t seconds = int32_t(sec)%60;
|
||||
int32_t minutes = int32_t(sec/60)%60;
|
||||
int32_t hours = sec/3600;
|
||||
std::string out;
|
||||
if (hours!=0) {
|
||||
out += etk::to_string(hours) + ":";
|
||||
}
|
||||
if (minutes<10) {
|
||||
out += " " + etk::to_string(minutes) + "'";
|
||||
} else {
|
||||
out += etk::to_string(minutes) + "'";
|
||||
}
|
||||
if (seconds<10) {
|
||||
out += " " + etk::to_string(seconds) + "\"";
|
||||
} else {
|
||||
out += etk::to_string(seconds) + "\"";
|
||||
}
|
||||
if (millisecond<10) {
|
||||
out += " 00" + etk::to_string(millisecond);
|
||||
} else if (millisecond<100) {
|
||||
out += " 0" + etk::to_string(millisecond);
|
||||
} else {
|
||||
out += etk::to_string(millisecond);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void appl::widget::Player::onCallbackDuration(const echrono::Duration& _time) {
|
||||
//APPL_ERROR("duration = " << _time);
|
||||
if (m_progress != nullptr) {
|
||||
m_progress->propertyValue.set(0);
|
||||
m_progress->propertyMaximum.set(_time.toSeconds());
|
||||
}
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]appl-player-label-duration", "value", "<font color='black'>" + timeToStaticString(_time) + "</font>");
|
||||
}
|
||||
|
||||
void appl::widget::Player::onCallbackPosition(const echrono::Duration& _time) {
|
||||
APPL_ERROR("time = " << _time);
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]appl-player-label-time", "value", "<font color='green'>" + etk::to_string(_time) + "</font>");
|
||||
//APPL_ERROR("time = " << _time);
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]appl-player-label-time", "value", "<font color='black'>" + timeToStaticString(_time) + "</font>");
|
||||
if (m_progress != nullptr) {
|
||||
m_progress->propertyValue.set(_time.toSeconds());
|
||||
}
|
||||
@ -99,7 +130,9 @@ void appl::widget::Player::onCallbackPosition(const echrono::Duration& _time) {
|
||||
}
|
||||
|
||||
void appl::widget::Player::onCallbackSeekRequest(const float& _value) {
|
||||
//APPL_ERROR("seek at = " << echrono::Duration(_value));
|
||||
APPL_ERROR("===========================================================================");
|
||||
APPL_ERROR("seek at = " << echrono::Duration(_value) << " from value=" << _value);
|
||||
APPL_ERROR("===========================================================================");
|
||||
if (m_display != nullptr) {
|
||||
m_display->seek(echrono::Duration(_value));
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ namespace appl {
|
||||
esignal::Signal<> signalFinished; //!< the play is finished
|
||||
esignal::Signal<> signalNext; //!< Next file is requested
|
||||
esignal::Signal<> signalPrevious; //!< Previous file is requested
|
||||
|
||||
protected:
|
||||
Player();
|
||||
void init() override;
|
||||
|
@ -63,7 +63,7 @@ void appl::widget::ProgressBar::onRegenerateDisplay() {
|
||||
// draw all availlable section ...
|
||||
m_draw.setColor(m_textColorLoaded);
|
||||
for (auto &it: m_listAvaillable) {
|
||||
APPL_INFO("plop " << it.first << " " << it.second);
|
||||
//APPL_INFO("plop " << it.first << " " << it.second);
|
||||
m_draw.setPos(vec3(dotRadius+(it.first/propertyMaximum)*(m_size.x()-2*dotRadius), m_size.y()*0.1, 0));
|
||||
m_draw.rectangleWidth(vec3((it.second/propertyMaximum)*(m_size.x()-2*dotRadius), m_size.y()*0.8, 0) );
|
||||
}
|
||||
|
@ -258,13 +258,12 @@ void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event)
|
||||
APPL_VERBOSE("tick: " << _event);
|
||||
m_currentTime += _event.getDeltaCallDuration();
|
||||
}
|
||||
|
||||
if (m_decoder == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (m_decoder->m_seekApply >= echrono::Duration(0)) {
|
||||
m_currentTime = m_decoder->m_seekApply;
|
||||
//APPL_ERROR("Apply new position : " << m_currentTime);
|
||||
APPL_ERROR("Apply new position : " << m_currentTime);
|
||||
m_decoder->m_seekApply = echrono::Duration(-1);
|
||||
if (m_audioInterface != nullptr) {
|
||||
m_audioInterface->clearInternalBuffer();
|
||||
@ -318,6 +317,13 @@ void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event)
|
||||
}
|
||||
// TODO : Chek if this is needed, the display configuration not change too much ...
|
||||
markToRedraw();
|
||||
if (m_haveDuration == true) {
|
||||
if (m_currentTime >= m_decoder->getDuration() + echrono::milliseconds(200)) {
|
||||
APPL_WARNING("Finish playing");
|
||||
signalFinish.emit();
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void appl::widget::VideoDisplay::seek(const echrono::Duration& _time) {
|
||||
|
@ -26,6 +26,7 @@ namespace appl {
|
||||
esignal::Signal<int32_t> signalFps;
|
||||
esignal::Signal<echrono::Duration> signalPosition; //!< signal the current duration of the video duration
|
||||
esignal::Signal<echrono::Duration> signalDuration; //!< signal the current duration of the video duration
|
||||
esignal::Signal<> signalFinish; //!< signal the playing is now finished
|
||||
bool m_haveDuration;
|
||||
private:
|
||||
mat4 m_matrixApply;
|
||||
|
7
tools/player-video/data/Group.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg height="100" width="100">
|
||||
<circle cx="50" cy="50" r="35" stroke="white" stroke-width="5" fill="black" />
|
||||
<circle cx="20" cy="35" r="10" stroke="white" stroke-width="5" fill="black" />
|
||||
<circle cx="80" cy="35" r="10" stroke="white" stroke-width="5" fill="black" />
|
||||
<circle cx="50" cy="85" r="10" stroke="white" stroke-width="5" fill="black" />
|
||||
</svg>
|
After Width: | Height: | Size: 412 B |
@ -2,10 +2,10 @@
|
||||
<svg width="64" height="64">
|
||||
<g transform="matrix(1.1999968,0,0,1.3606385,-147.9521,-648.3007)">
|
||||
<path d="m 170.351,504.021 c -0.343,0.365 -0.922,0.385 -1.288,0.043 L 150.392,486.63 c -0.365,-0.342 -0.966,-0.342 -1.332,0 l -18.204,16.97 c -0.367,0.344 -0.945,0.322 -1.287,-0.045 l -1.865,-2 c -0.342,-0.365 -0.321,-0.945 0.045,-1.287 l 21.313,-19.869 c 0.367,-0.342 0.967,-0.342 1.334,0.002 l 21.777,20.334 c 0.365,0.342 0.386,0.922 0.043,1.289 l -1.865,1.997 z"
|
||||
style="fill:#333333"/>
|
||||
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px"/>
|
||||
<path d="m 149.725,489.777 -15.345,14.305 v 14.83 c 0,0.504 0.414,0.918 0.919,0.918 h 10.085 v -12.857 c 0,-0.504 0.414,-0.918 0.919,-0.918 h 7.347 c 0.506,0 0.918,0.414 0.918,0.918 v 12.857 h 10.119 c 0.505,0 0.918,-0.414 0.918,-0.918 v -14.307 l -15.88,-14.828 z"
|
||||
style="fill:#333333"/>
|
||||
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px"/>
|
||||
<path d="m 165.543,482.311 c 0,-0.506 -0.414,-0.92 -0.919,-0.92 h -5.51 c -0.505,0 -0.918,0.414 -0.918,0.92 v 1.604 l 7.347,6.918 v -8.522 z"
|
||||
style="fill:#333333"/>
|
||||
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
@ -2,10 +2,10 @@
|
||||
<svg width="64" height="64">
|
||||
<g transform="matrix(1.1999733,0,0,1.1999733,-364.43055,-494.42419)">
|
||||
<path d="m 352.572,429.142 c 0,0.494 -0.406,0.9 -0.9,0.9 h -43.201 c -0.494,0 -0.9,-0.406 -0.9,-0.9 v -8.099 c 0,-0.496 0.406,-0.9 0.9,-0.9 h 43.201 c 0.494,0 0.9,0.404 0.9,0.9 v 8.099 z"
|
||||
style="fill:#333333" />
|
||||
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px" />
|
||||
<path d="m 352.572,443.542 c 0,0.494 -0.406,0.9 -0.9,0.9 h -43.201 c -0.494,0 -0.9,-0.406 -0.9,-0.9 v -8.1 c 0,-0.496 0.406,-0.9 0.9,-0.9 h 43.201 c 0.494,0 0.9,0.404 0.9,0.9 v 8.1 z"
|
||||
style="fill:#333333" />
|
||||
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px" />
|
||||
<path d="m 352.572,457.942 c 0,0.494 -0.406,0.898 -0.9,0.898 h -43.201 c -0.494,0 -0.9,-0.404 -0.9,-0.898 v -8.102 c 0,-0.494 0.406,-0.898 0.9,-0.898 h 43.201 c 0.494,0 0.9,0.404 0.9,0.898 v 8.102 z"
|
||||
style="fill:#333333" />
|
||||
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 842 B After Width: | Height: | Size: 938 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="64" height="64">
|
||||
<path style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
<path style="fill:#000000;fill-rule:evenodd;stroke:#FFFFFF;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="M 16,52 16,62 51,31.991525 16.003261,2.0107803 16,12 39.259882,32.095879 16,52"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 335 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="64" height="64">
|
||||
<path style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
<path style="fill:#000000;fill-rule:evenodd;stroke:#FFFFFF;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
|
||||
d="M 15,2 52,32 15,62 Z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 277 B After Width: | Height: | Size: 277 B |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="64" height="64">
|
||||
<path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
<path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#FFFFFF;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 51.26828,52 0,10 -35,-30.008475 L 51.265019,2.0107803 51.26828,12 28.008398,32.095879 51.26828,52"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 356 B |
@ -3,23 +3,32 @@
|
||||
<sizer mode="hori" fill="true" expand="true,false">
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<button name="[{ID}]appl-player-bt-previous">
|
||||
<label>_T{Previous}</label>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<button name="[{ID}]appl-player-bt-previous" shape="">
|
||||
<!--<label>_T{Previous}</label>-->
|
||||
<image src="DATA:Previous.svg" size="8,8mm"/>
|
||||
</button>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<button name="[{ID}]appl-player-bt-play" toggle="true">
|
||||
<label>_T{Play}</label>
|
||||
<button name="[{ID}]appl-player-bt-play" toggle="true" shape="">
|
||||
<!--<label>_T{Play}</label>-->
|
||||
<image src="DATA:Play.svg" size="8,8mm"/>
|
||||
<label>_T{Pause}</label>
|
||||
</button>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<button name="[{ID}]appl-player-bt-next">
|
||||
<label>_T{Next}</label>
|
||||
<button name="[{ID}]appl-player-bt-next" shape="">
|
||||
<!--<label>_T{Next}</label>-->
|
||||
<image src="DATA:Next.svg" size="8,8mm" />
|
||||
</button>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<label name="[{ID}]appl-player-label-time"/>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
</sizer>
|
||||
<appl_ProgressBar name="[{ID}]appl-player-progress-bar" expand="true,false" fill="true" step="0.01" min="0"/>
|
||||
<sizer mode="hori" fill="true" expand="true,false">
|
||||
<label name="[{ID}]appl-player-label-time"/>
|
||||
<spacer expand="true,false" fill="true"/>
|
||||
<label name="[{ID}]appl-player-label-duration"/>
|
||||
</sizer>
|
||||
<spacer expand="true" fill="true"/>
|
||||
<label name="[{ID}]appl-player-label-fps"/>
|
||||
</sizer>
|
||||
|
@ -38,21 +38,21 @@
|
||||
<player name="ws-name-player" fill="true" expand="true"/>
|
||||
</wslider>
|
||||
<sizer mode="hori" fill="true" expand="true,false" lock="true">
|
||||
<button name="access-fast-home">
|
||||
<image src="DATA:Home.svg" size='8,8mm' />
|
||||
<button name="access-fast-home" shape="">
|
||||
<image src="DATA:Home.svg" size="8,8mm" />
|
||||
</button>
|
||||
<button name="access-fast-group">
|
||||
<image src="DATA:Group.svg" size='8,8mm' />
|
||||
<button name="access-fast-group" shape="">
|
||||
<image src="DATA:Group.svg" size="8,8mm" />
|
||||
</button>
|
||||
<!--
|
||||
<button name="access-fast-tv">
|
||||
<image src="DATA:Tv.svg" size='8,8mm' />
|
||||
<image src="DATA:Tv.svg" size="8,8mm" />
|
||||
</button>
|
||||
<button name="access-fast-page-previous">
|
||||
<image src="DATA:Previous.svg" size='8,8mm' />
|
||||
<image src="DATA:Previous.svg" size="8,8mm" />
|
||||
</button>
|
||||
<button name="access-fast-page-next">
|
||||
<image src="DATA:Next.svg" size='8,8mm' />
|
||||
<image src="DATA:Next.svg" size="8,8mm" />
|
||||
</button>
|
||||
-->
|
||||
</sizer>
|
||||
@ -79,7 +79,7 @@
|
||||
</elem>
|
||||
</menu>
|
||||
<entry name="search-entry" fill="true,false" expand="true,false"/>
|
||||
<button name="search-bt">
|
||||
<button name="search-bt" shape="">
|
||||
<image src="DATA:Search.svg" size='8,8mm' />
|
||||
</button>
|
||||
</sizer>
|
||||
|