Fix UNC paths.
The fix-up for URLs for files that that begin with // no longer works since the QUrl class determines that these modifications are invalid, resulting in an empty string when converted. Instead of attempting to modify the QUrl, add a utility function that makes the correction on the encoded byte array at time of usage.
This commit is contained in:
parent
e575a1da9f
commit
d3d6c1ff3c
|
@ -404,7 +404,8 @@ SongLoader::Result SongLoader::LoadRemote() {
|
||||||
|
|
||||||
// Create the source element automatically based on the URL
|
// Create the source element automatically based on the URL
|
||||||
GstElement* source = gst_element_make_from_uri(
|
GstElement* source = gst_element_make_from_uri(
|
||||||
GST_URI_SRC, url_.toEncoded().constData(), nullptr, nullptr);
|
GST_URI_SRC, Utilities::GetUriForGstreamer(url_).constData(),
|
||||||
|
nullptr, nullptr);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
qLog(Warning) << "Couldn't create gstreamer source element for"
|
qLog(Warning) << "Couldn't create gstreamer source element for"
|
||||||
<< url_.toString();
|
<< url_.toString();
|
||||||
|
|
|
@ -741,6 +741,17 @@ QString FiddleFileExtension(const QString& filename,
|
||||||
return PathWithoutFilenameExtension(filename) + "." + new_extension;
|
return PathWithoutFilenameExtension(filename) + "." + new_extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray GetUriForGstreamer(const QUrl& url) {
|
||||||
|
if (url.scheme() == "file") {
|
||||||
|
QString local_file = url.toLocalFile();
|
||||||
|
if (local_file.indexOf("//") == 0) {
|
||||||
|
// Exclude / from encoding.
|
||||||
|
return QByteArray("file://") + QUrl::toPercentEncoding(local_file, "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url.toEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Utilities
|
} // namespace Utilities
|
||||||
|
|
||||||
ScopedWCharArray::ScopedWCharArray(const QString& str)
|
ScopedWCharArray::ScopedWCharArray(const QString& str)
|
||||||
|
|
|
@ -123,6 +123,10 @@ QString PathWithoutFilenameExtension(const QString& filename);
|
||||||
QString FiddleFileExtension(const QString& filename,
|
QString FiddleFileExtension(const QString& filename,
|
||||||
const QString& new_extension);
|
const QString& new_extension);
|
||||||
|
|
||||||
|
// Fix URLs for Gstreamer, specifically those for network file paths that begin
|
||||||
|
// with //.
|
||||||
|
QByteArray GetUriForGstreamer(const QUrl& url);
|
||||||
|
|
||||||
enum ConfigPath {
|
enum ConfigPath {
|
||||||
Path_Root,
|
Path_Root,
|
||||||
Path_Icons,
|
Path_Icons,
|
||||||
|
|
|
@ -368,29 +368,13 @@ void GstEngine::StartPreloading(const QUrl& url, bool force_stop_at_end,
|
||||||
qint64 beginning_nanosec, qint64 end_nanosec) {
|
qint64 beginning_nanosec, qint64 end_nanosec) {
|
||||||
EnsureInitialised();
|
EnsureInitialised();
|
||||||
|
|
||||||
QUrl gst_url = FixupUrl(url);
|
|
||||||
|
|
||||||
// No crossfading, so we can just queue the new URL in the existing
|
// No crossfading, so we can just queue the new URL in the existing
|
||||||
// pipeline and get gapless playback (hopefully)
|
// pipeline and get gapless playback (hopefully)
|
||||||
if (current_pipeline_)
|
if (current_pipeline_)
|
||||||
current_pipeline_->SetNextUrl(gst_url, beginning_nanosec,
|
current_pipeline_->SetNextUrl(url, beginning_nanosec,
|
||||||
force_stop_at_end ? end_nanosec : 0);
|
force_stop_at_end ? end_nanosec : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl GstEngine::FixupUrl(const QUrl& url) {
|
|
||||||
QUrl copy = url;
|
|
||||||
|
|
||||||
// It's a file:// url with a hostname set. QUrl::fromLocalFile does this
|
|
||||||
// when given a \\host\share\file path on Windows. Munge it back into a
|
|
||||||
// path that gstreamer will recognise.
|
|
||||||
if (url.scheme() == "file" && !url.host().isEmpty()) {
|
|
||||||
copy.setPath("//" + copy.host() + copy.path());
|
|
||||||
copy.setHost(QString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GstEngine::Load(const QUrl& url, Engine::TrackChangeFlags change,
|
bool GstEngine::Load(const QUrl& url, Engine::TrackChangeFlags change,
|
||||||
bool force_stop_at_end, quint64 beginning_nanosec,
|
bool force_stop_at_end, quint64 beginning_nanosec,
|
||||||
qint64 end_nanosec) {
|
qint64 end_nanosec) {
|
||||||
|
@ -399,8 +383,6 @@ bool GstEngine::Load(const QUrl& url, Engine::TrackChangeFlags change,
|
||||||
Engine::Base::Load(url, change, force_stop_at_end, beginning_nanosec,
|
Engine::Base::Load(url, change, force_stop_at_end, beginning_nanosec,
|
||||||
end_nanosec);
|
end_nanosec);
|
||||||
|
|
||||||
QUrl gst_url = FixupUrl(url);
|
|
||||||
|
|
||||||
bool crossfade =
|
bool crossfade =
|
||||||
current_pipeline_ && ((crossfade_enabled_ && change & Engine::Manual) ||
|
current_pipeline_ && ((crossfade_enabled_ && change & Engine::Manual) ||
|
||||||
(autocrossfade_enabled_ && change & Engine::Auto) ||
|
(autocrossfade_enabled_ && change & Engine::Auto) ||
|
||||||
|
@ -411,7 +393,7 @@ bool GstEngine::Load(const QUrl& url, Engine::TrackChangeFlags change,
|
||||||
!crossfade_same_album_)
|
!crossfade_same_album_)
|
||||||
crossfade = false;
|
crossfade = false;
|
||||||
|
|
||||||
if (!crossfade && current_pipeline_ && current_pipeline_->url() == gst_url &&
|
if (!crossfade && current_pipeline_ && current_pipeline_->url() == url &&
|
||||||
change & Engine::Auto) {
|
change & Engine::Auto) {
|
||||||
// We're not crossfading, and the pipeline is already playing the URI we
|
// We're not crossfading, and the pipeline is already playing the URI we
|
||||||
// want, so just do nothing.
|
// want, so just do nothing.
|
||||||
|
@ -419,7 +401,7 @@ bool GstEngine::Load(const QUrl& url, Engine::TrackChangeFlags change,
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<GstEnginePipeline> pipeline =
|
shared_ptr<GstEnginePipeline> pipeline =
|
||||||
CreatePipeline(gst_url, force_stop_at_end ? end_nanosec : 0);
|
CreatePipeline(url, force_stop_at_end ? end_nanosec : 0);
|
||||||
if (!pipeline) return false;
|
if (!pipeline) return false;
|
||||||
|
|
||||||
if (crossfade) StartFadeout();
|
if (crossfade) StartFadeout();
|
||||||
|
|
|
@ -169,8 +169,6 @@ class GstEngine : public Engine::Base, public BufferConsumer {
|
||||||
|
|
||||||
int AddBackgroundStream(std::shared_ptr<GstEnginePipeline> pipeline);
|
int AddBackgroundStream(std::shared_ptr<GstEnginePipeline> pipeline);
|
||||||
|
|
||||||
static QUrl FixupUrl(const QUrl& url);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const qint64 kTimerIntervalNanosec = 1000 * kNsecPerMsec; // 1s
|
static const qint64 kTimerIntervalNanosec = 1000 * kNsecPerMsec; // 1s
|
||||||
static const qint64 kPreloadGapNanosec = 2000 * kNsecPerMsec; // 2s
|
static const qint64 kPreloadGapNanosec = 2000 * kNsecPerMsec; // 2s
|
||||||
|
|
|
@ -204,7 +204,7 @@ GstElement* GstEnginePipeline::CreateDecodeBinFromUrl(const QUrl& url) {
|
||||||
str.remove(str.lastIndexOf(QChar('a')), 1);
|
str.remove(str.lastIndexOf(QChar('a')), 1);
|
||||||
uri = str.toUtf8();
|
uri = str.toUtf8();
|
||||||
} else {
|
} else {
|
||||||
uri = url.toEncoded();
|
uri = Utilities::GetUriForGstreamer(url);
|
||||||
}
|
}
|
||||||
new_bin = engine_->CreateElement("uridecodebin");
|
new_bin = engine_->CreateElement("uridecodebin");
|
||||||
if (!new_bin) return nullptr;
|
if (!new_bin) return nullptr;
|
||||||
|
|
|
@ -103,8 +103,8 @@ void MoodbarPipeline::Start() {
|
||||||
builder_.reset(new MoodbarBuilder);
|
builder_.reset(new MoodbarBuilder);
|
||||||
|
|
||||||
// Set properties
|
// Set properties
|
||||||
g_object_set(decodebin, "uri", local_filename_.toEncoded().constData(),
|
QByteArray uri = Utilities::GetUriForGstreamer(local_filename_);
|
||||||
nullptr);
|
g_object_set(decodebin, "uri", uri.constData(), nullptr);
|
||||||
g_object_set(spectrum, "bands", kBands, nullptr);
|
g_object_set(spectrum, "bands", kBands, nullptr);
|
||||||
|
|
||||||
GstFastSpectrum* fast_spectrum = GST_FASTSPECTRUM(spectrum);
|
GstFastSpectrum* fast_spectrum = GST_FASTSPECTRUM(spectrum);
|
||||||
|
|
Loading…
Reference in New Issue