@@ -27,13 +27,15 @@ func ProcessJfWebhook(jfChan chan<- models.JellyfinWebhook, c *gin.Context) {
27
27
read , err := io .ReadAll (r )
28
28
if err != nil {
29
29
log .Errorf ("Error reading request body: %v" , err )
30
+ return
30
31
}
31
32
32
- // log.Debugf("ProcessJfWebhook Request: %v", string(read))
33
33
var payload models.JellyfinWebhook
34
34
err = json .Unmarshal (read , & payload )
35
35
if err != nil {
36
36
log .Errorf ("Error decoding payload: %v" , err )
37
+ log .Debugf ("ProcessJfWebhook Request: %v" , string (read ))
38
+ return
37
39
}
38
40
log .Debugf ("Payload: %#v" , payload )
39
41
// respond to request with 200
@@ -48,7 +50,7 @@ func jfEventRouter(jfClient *jellyfin.JellyfinClient, beqClient *ezbeq.BeqClient
48
50
clientUUID := payload .ClientName
49
51
// ensure the client matches so it doesnt trigger from unwanted clients
50
52
51
- if ! checkUUID (clientUUID , config .GetString ("plex .deviceUUIDFilter" )) {
53
+ if ! checkUUID (clientUUID , config .GetString ("jellyfin .deviceUUIDFilter" )) {
52
54
log .Infof ("Got a webhook but Client UUID '%s' does not match enabled filter" , clientUUID )
53
55
return
54
56
}
@@ -61,6 +63,7 @@ func jfEventRouter(jfClient *jellyfin.JellyfinClient, beqClient *ezbeq.BeqClient
61
63
metadata , err := jfClient .GetMetadata (payload .UserID , payload .ItemID )
62
64
if err != nil {
63
65
log .Errorf ("Error getting metadata from jellyfin API: %v" , err )
66
+ return
64
67
}
65
68
66
69
log .Debugf ("Processing media type: %s" , metadata .Type )
@@ -116,26 +119,25 @@ func jfEventRouter(jfClient *jellyfin.JellyfinClient, beqClient *ezbeq.BeqClient
116
119
switch payload .NotificationType {
117
120
// unload BEQ on pause OR stop because I never press stop, just pause and then back.
118
121
case "PlaybackStart" :
119
- log . Debug ( "Event Router: media.play received" )
122
+ // TODO: test start/resume/pause
120
123
jfMediaPlay (jfClient , beqClient , haClient , payload , model , false , data , skipActions )
121
124
case "PlaybackStop" :
122
- log .Debug ("Event Router: media.stop received" )
123
125
jfMediaStop (jfClient , beqClient , haClient , payload , model , false , data , skipActions )
124
126
// really annoyingly jellyfin doesnt send a pause or resume event only progress every X seconds with a isPaused flag
125
127
// TODO: support pause resume without running resume on every playbackprogress
126
- // case "PlaybackProgress":
127
- // log.Debug("Event Router: PlaybackProgress received")
128
- // if payload.IsPaused == "true" {
129
- // mediaPause(beqClient, haClient, payload, model, skipActions)
130
- // } else {
131
- // mediaResume()
132
- // }
128
+ case "PlaybackProgress" :
129
+ if payload .IsPaused == "true" {
130
+ jfMediaPause (beqClient , haClient , payload , model , skipActions )
131
+ } else {
132
+ jfMediaResume (jfClient , beqClient , haClient , payload , model , false , data , skipActions )
133
+ }
133
134
default :
134
135
log .Warnf ("Received unsupported webhook event. Nothing to do: %s" , payload .NotificationType )
135
136
}
136
137
}
137
138
138
139
func jfMediaPlay (client * jellyfin.JellyfinClient , beqClient * ezbeq.BeqClient , haClient * homeassistant.HomeAssistantClient , payload models.JellyfinWebhook , m * models.SearchRequest , useDenonCodec bool , data models.JellyfinMetadata , skipActions * bool ) {
140
+ log .Debug ("Processing media play event" )
139
141
wg := & sync.WaitGroup {}
140
142
141
143
// stop processing webhooks
@@ -172,8 +174,12 @@ func jfMediaPlay(client *jellyfin.JellyfinClient, beqClient *ezbeq.BeqClient, ha
172
174
173
175
m .TMDB , err = client .GetJfTMDB (data )
174
176
if err != nil {
175
- log .Errorf ("Error getting TMDB data from metadata: %v" , err )
176
- return
177
+ if config .GetBool ("jellyfin.skiptmdb" ) {
178
+ log .Warn ("TMDB data not found. TMDB is allowed to be skipped" )
179
+ } else {
180
+ log .Errorf ("Error getting TMDB data from metadata: %v" , err )
181
+ return
182
+ }
177
183
}
178
184
err = beqClient .LoadBeqProfile (m )
179
185
if err != nil {
@@ -196,15 +202,118 @@ func jfMediaPlay(client *jellyfin.JellyfinClient, beqClient *ezbeq.BeqClient, ha
196
202
}
197
203
198
204
func jfMediaStop (client * jellyfin.JellyfinClient , beqClient * ezbeq.BeqClient , haClient * homeassistant.HomeAssistantClient , payload models.JellyfinWebhook , m * models.SearchRequest , useDenonCodec bool , data models.JellyfinMetadata , skipActions * bool ) {
199
- return
200
- // TODO: implement
205
+ log .Debug ("Processing media stop event" )
206
+ err := mqtt .PublishWrapper (config .GetString ("mqtt.topicplayingstatus" ), "false" )
207
+ if err != nil {
208
+ log .Error (err )
209
+ }
210
+ go common .ChangeLight ("on" )
211
+
212
+ err = beqClient .UnloadBeqProfile (m )
213
+ if err != nil {
214
+ log .Error (err )
215
+ if config .GetBool ("ezbeq.notifyOnLoad" ) && config .GetBool ("homeAssistant.enabled" ) {
216
+ err := haClient .SendNotification (fmt .Sprintf ("Error UNLOADING profile: %v -- Unsafe to play movies!" , err ))
217
+ if err != nil {
218
+ log .Error ()
219
+ }
220
+ }
221
+ }
222
+ log .Info ("BEQ profile unloaded" )
223
+ }
224
+
225
+ func jfMediaPause (beqClient * ezbeq.BeqClient , haClient * homeassistant.HomeAssistantClient , payload models.JellyfinWebhook , m * models.SearchRequest , skipActions * bool ) {
226
+ log .Debug ("Processing media pause event" )
227
+ if ! * skipActions {
228
+ err := mqtt .PublishWrapper (config .GetString ("mqtt.topicplayingstatus" ), "false" )
229
+ if err != nil {
230
+ log .Error (err )
231
+ }
232
+
233
+ go common .ChangeLight ("on" )
234
+
235
+ err = beqClient .UnloadBeqProfile (m )
236
+ if err != nil {
237
+ log .Error (err )
238
+ if config .GetBool ("ezbeq.notifyOnLoad" ) && config .GetBool ("homeAssistant.enabled" ) {
239
+ err := haClient .SendNotification (fmt .Sprintf ("Error UNLOADING profile: %v -- Unsafe to play movies!" , err ))
240
+ if err != nil {
241
+ log .Error ()
242
+ }
243
+ }
244
+ }
245
+ log .Info ("BEQ profile unloaded" )
246
+ }
247
+ }
248
+ func jfMediaResume (client * jellyfin.JellyfinClient , beqClient * ezbeq.BeqClient , haClient * homeassistant.HomeAssistantClient , payload models.JellyfinWebhook , m * models.SearchRequest , useDenonCodec bool , data models.JellyfinMetadata , skipActions * bool ) {
249
+ log .Debug ("Processing media resume event" )
250
+ if ! * skipActions {
251
+ // mediaType string, codec string, edition string
252
+ // trigger lights
253
+ err := mqtt .PublishWrapper (config .GetString ("mqtt.topicplayingstatus" ), "true" )
254
+ if err != nil {
255
+ log .Error (err )
256
+ }
257
+ go common .ChangeLight ("off" )
258
+ // Changing on resume is disabled because its annoying if you changed it since playing
259
+ // go changeMasterVolume(vip, mediaType)
260
+
261
+ // allow skipping search to save time
262
+ // always unload in case something is loaded from movie for tv
263
+ err = beqClient .UnloadBeqProfile (m )
264
+ if err != nil {
265
+ log .Errorf ("Error on startup - unloading beq %v" , err )
266
+ }
267
+ if data .Type == showItemTitle {
268
+ if ! config .GetBool ("ezbeq.enableTvBeq" ) {
269
+ return
270
+ }
271
+ }
272
+ // get the tmdb id to match with ezbeq catalog
273
+ m .TMDB , err = client .GetJfTMDB (data )
274
+ if err != nil {
275
+ log .Errorf ("Error getting TMDB data from metadata: %v" , err )
276
+ return
277
+ }
278
+ // if the server was restarted, cached data is lost
279
+ if m .Codec == "" {
280
+ log .Warn ("No codec found in cache on resume. Was server restarted? Getting new codec" )
281
+ log .Debug ("Using jellyfin to get codec because its not cached" )
282
+ m .Codec , err = client .GetAudioCodec (data )
283
+ if err != nil {
284
+ log .Errorf ("error getting codec from jellyfin, can't continue: %s" , err )
285
+ return
286
+ }
287
+ }
288
+ if m .Codec == "" {
289
+ log .Error ("No codec found after trying to resume" )
290
+ return
291
+ }
292
+
293
+ err = beqClient .LoadBeqProfile (m )
294
+ if err != nil {
295
+ log .Error (err )
296
+ return
297
+ }
298
+ log .Info ("BEQ profile loaded" )
299
+
300
+ // send notification of it loaded
301
+ if config .GetBool ("ezbeq.notifyOnLoad" ) && config .GetBool ("homeAssistant.enabled" ) {
302
+ err := haClient .SendNotification (fmt .Sprintf ("BEQ Profile: Title - %s (%s) // Codec %s" , data .OriginalTitle , payload .Year , m .Codec ))
303
+ if err != nil {
304
+ log .Error ()
305
+ }
306
+ }
307
+ }
201
308
}
202
309
203
310
// // entry point for background tasks
204
311
func JellyfinWorker (jfChan <- chan models.JellyfinWebhook , readyChan chan <- bool ) {
205
- readyChan <- true
206
-
207
- log .Info ("JellyfinWorker started" )
312
+ if ! config .GetBool ("jellyfin.enabled" ) {
313
+ log .Debug ("Jellyfin is disabled" )
314
+ readyChan <- true
315
+ return
316
+ }
208
317
209
318
// Server Info
210
319
jellyfinClient := jellyfin .NewClient (config .GetString ("jellyfin.url" ), config .GetString ("jellyfin.port" ), config .GetString ("jellyfin.playerMachineIdentifier" ), config .GetString ("jellyfin.playerIP" ))
0 commit comments