Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
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
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
abd41673
Commit
abd41673
authored
4 years ago
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
output/snapcast: implement SendTag()
parent
6090bd20
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
105 additions
and
2 deletions
+105
-2
meson.build
src/output/plugins/meson.build
+3
-1
Client.cxx
src/output/plugins/snapcast/Client.cxx
+21
-0
Client.hxx
src/output/plugins/snapcast/Client.hxx
+2
-0
Internal.hxx
src/output/plugins/snapcast/Internal.hxx
+1
-1
SnapcastOutputPlugin.cxx
src/output/plugins/snapcast/SnapcastOutputPlugin.cxx
+78
-0
No files found.
src/output/plugins/meson.build
View file @
abd41673
...
...
@@ -119,7 +119,9 @@ if get_option('snapcast')
'snapcast/SnapcastOutputPlugin.cxx',
'snapcast/Client.cxx',
]
output_plugins_deps += [ event_dep, net_dep ]
output_plugins_deps += [ event_dep, net_dep, yajl_dep ]
output_features.set('HAVE_YAJL', yajl_dep.found())
# TODO: the Snapcast plugin needs just the "wave" encoder, but this
# enables all available encoders
...
...
This diff is collapsed.
Click to expand it.
src/output/plugins/snapcast/Client.cxx
View file @
abd41673
...
...
@@ -236,6 +236,27 @@ SnapcastClient::SendWireChunk(ConstBuffer<void> payload,
return
::
SendWireChunk
(
GetSocket
(),
next_id
++
,
payload
,
t
);
}
static
bool
SendStreamTags
(
SocketDescriptor
s
,
const
PackedBE16
id
,
const
ConstBuffer
<
void
>
payload
)
noexcept
{
const
PackedLE32
payload_size
=
payload
.
size
;
SnapcastBase
base
{};
base
.
type
=
uint16_t
(
SnapcastMessageType
::
STREAM_TAGS
);
base
.
id
=
id
;
base
.
sent
=
ToSnapcastTimestamp
(
std
::
chrono
::
steady_clock
::
now
());
base
.
size
=
sizeof
(
payload_size
)
+
payload
.
size
;
return
SendT
(
s
,
base
)
&&
SendT
(
s
,
payload_size
)
&&
Send
(
s
,
payload
);
}
void
SnapcastClient
::
SendStreamTags
(
ConstBuffer
<
void
>
payload
)
noexcept
{
::
SendStreamTags
(
GetSocket
(),
next_id
++
,
payload
);
}
BufferedSocket
::
InputResult
SnapcastClient
::
OnSocketInput
(
void
*
data
,
size_t
length
)
noexcept
{
...
...
This diff is collapsed.
Click to expand it.
src/output/plugins/snapcast/Client.hxx
View file @
abd41673
...
...
@@ -60,6 +60,8 @@ public:
void
LockClose
()
noexcept
;
void
SendStreamTags
(
ConstBuffer
<
void
>
payload
)
noexcept
;
/**
* Caller must lock the mutex.
*/
...
...
This diff is collapsed.
Click to expand it.
src/output/plugins/snapcast/Internal.hxx
View file @
abd41673
...
...
@@ -165,7 +165,7 @@ public:
std
::
chrono
::
steady_clock
::
duration
Delay
()
const
noexcept
override
;
// TODO:
void SendTag(const Tag &tag) override;
void
SendTag
(
const
Tag
&
tag
)
override
;
size_t
Play
(
const
void
*
chunk
,
size_t
size
)
override
;
...
...
This diff is collapsed.
Click to expand it.
src/output/plugins/snapcast/SnapcastOutputPlugin.cxx
View file @
abd41673
...
...
@@ -21,6 +21,7 @@
#include "Internal.hxx"
#include "Client.hxx"
#include "output/OutputAPI.hxx"
#include "output/Features.h"
#include "encoder/EncoderInterface.hxx"
#include "encoder/Configured.hxx"
#include "encoder/plugins/WaveEncoderPlugin.hxx"
...
...
@@ -31,6 +32,10 @@
#include "util/DeleteDisposer.hxx"
#include "config/Net.hxx"
#ifdef HAVE_YAJL
#include "lib/yajl/Gen.hxx"
#endif
#include <cassert>
#include <string.h>
...
...
@@ -207,6 +212,79 @@ SnapcastOutput::Delay() const noexcept
:
std
::
chrono
::
steady_clock
::
duration
::
zero
();
}
#ifdef HAVE_YAJL
static
constexpr
struct
{
TagType
type
;
const
char
*
name
;
}
snapcast_tags
[]
=
{
/* these tags are mentioned in an example in
snapcast/common/message/stream_tags.hpp */
{
TAG_ARTIST
,
"artist"
},
{
TAG_ALBUM
,
"album"
},
{
TAG_TITLE
,
"track"
},
{
TAG_MUSICBRAINZ_TRACKID
,
"musicbrainzid"
},
};
static
bool
TranslateTagType
(
Yajl
::
Gen
&
gen
,
const
Tag
&
tag
,
TagType
type
,
const
char
*
name
)
noexcept
{
// TODO: support multiple values?
const
char
*
value
=
tag
.
GetValue
(
type
);
if
(
value
==
nullptr
)
return
false
;
gen
.
String
(
name
);
gen
.
String
(
value
);
return
true
;
}
static
std
::
string
ToJson
(
const
Tag
&
tag
)
noexcept
{
Yajl
::
Gen
gen
(
nullptr
);
gen
.
OpenMap
();
bool
empty
=
true
;
for
(
const
auto
[
type
,
name
]
:
snapcast_tags
)
if
(
TranslateTagType
(
gen
,
tag
,
type
,
name
))
empty
=
false
;
if
(
empty
)
return
{};
gen
.
CloseMap
();
const
auto
result
=
gen
.
GetBuffer
();
return
{(
const
char
*
)
result
.
data
,
result
.
size
};
}
#endif
void
SnapcastOutput
::
SendTag
(
const
Tag
&
tag
)
{
#ifdef HAVE_YAJL
if
(
!
LockHasClients
())
return
;
const
auto
json
=
ToJson
(
tag
);
if
(
json
.
empty
())
return
;
const
ConstBuffer
payload
(
json
.
data
(),
json
.
size
());
const
std
::
lock_guard
<
Mutex
>
protect
(
mutex
);
// TODO: enqueue StreamTags, don't send directly
for
(
auto
&
client
:
clients
)
client
.
SendStreamTags
(
payload
.
ToVoid
());
#else
(
void
)
tag
;
#endif
}
size_t
SnapcastOutput
::
Play
(
const
void
*
chunk
,
size_t
size
)
{
...
...
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