How to loop play sound files [Solved]

I’m unfamiliar with all of media_player’s service. Is the play_media service the only one available to set (enqueue) media?


Not that it’s particularly relevant to this conversation but, just for comparison, in Premise I can assign media to a player without having to play it at that moment (i.e. assigning media and playing it can be separate actions).

I beg to differ, and think it is of utmost relevance … but I can’t tell you tbh. Just have started using this service really.

probably in here: core/homeassistant/components/media_player/__init__.py at dev · home-assistant/core · GitHub

while the docs on media_player don’t really answer these kind of questions: Media player - Home Assistant

as far as I can tell one needs to use one of the available services, to have the attributes set, and I only see the relevant option to be media_player.play_media.

unless one could directly check a media file for its duration, which probably is possible. maybe even using python or some other command which we can use in the yaml code.

btw note the docs states media_player.media_play, while in fact we use media_player.play_media…

I searched through the services file and the only one that lets you assign media is the one you’re already using (media_player.play_media).

An ugly workaround would be to call play_media then immediately call media_stop. Perhaps it’s insufficient time to hear anything but just enough to set the media_duration attribute. Once the duration is known, then the timer’s duration can be set and started.

I’ve come to this a bit late but am finding it very interesting. It has been a holy grail of mine for almost as long as I have been using HA to come up with a fully transportable TTS notification package that can deal with all (ha! ha!) possibilities involving many media players, many standard or built-on-the-fly announcements (or other media) which can be called from many places at unspecified times with variable pauses in between them.

The main, but not the only stumbling block, has always been finding a way to implement a robust message queue in yaml. I now have a slightly ugly solution that covers most of my requirements including pauses and looping (my siren media and spoken warnings for my alarm) but it is not fool-proof and certainly not portable.

However, to get to my point…

an even uglier, but maybe better in that you definitely won’t hear the TTS the first time, while getting the duration, would be to set the volume to zero, then

and then set the volume back to what it was before actually playing the TTS/media.

I would be very interested in that too. Have a home made sequence for interrupting a playing media_player fir an announcement and resuming afterwards, but since Ive only been using tts about a week, wouldn’t call it mature… hope to learn fro your experience on the matter!

have tried @123’s workaround, but it wouldn’t really work tbh. Its all in the timing, and even with that ‘hack’ things don’t work as one would desire. Understand what your improvement would do and one could even add a small delay so to be sure the media_duration was set.

still, adding an extra input for saving the volume and restoring it makes this even more complex.
And my final solution is working alright.

Though it feels rather incomplete HA hasn’t got a better way of determining the media_duration (which is an attribute of the media_player) or even play_length as attribute of a media_file itself!

Hope my future request for native media_player.play_loop gets some attention, because that would finally make this as it should be.

@Mariusthvdb

I’ll take a moment to explain how it works in Premise, perhaps to serve as inspiration for Home Assistant’s developers to implement similar features. I think you’ll find this interesting.

In Premise, a MediaZone object is similar to Home Assistant’s media_player component. Both are an abstracted model of ‘stuff that plays media’. However, Premise’s MediaZone offers more functionality.

Before I explain a MediaZone object, I’ll take a moment to describe what’s shown in the Explorer pane (see top of image). It’s a hierarchical view of all (automated) objects in my home.

Home Assistant recently included support for Areas. In Premise they are called Locations and they can be organized in a hierarchy. It’s not just eye-candy; it’s used to define the physical location of everything. The ‘fully-qualified’ name of the KitchenMediaZone object is:

Home.House.First.Kitchen.KitchenMediaZone

You can, for example, turn on all Light objects in Home.House.First.Kitchen or turn off all MediaZone objects in Home.House.First or turn off everything in Home.House. Each Location has its own properties (like aggregated temperature and power-state). You don’t see it in this view but I also have a Home.Shed and Home.Outside.

In Home Assistant, a component has a state, attributes, and services. In Premise, an object has properties and methods (properties = state + attributes, methods = services). Referring to the image again, the Properties pane is currently showing all of the KitchenMediaZone’s properties (and methods). This is a live view like the States page in Home Assistant. However, unlike the States page, I can control the object by changing its properties in the Properties pane.

Imagine if Home Assistant’s States and Services pages were combined into one. That would be similar to (but still not equivalent) to what can be done in Premise’s Properties pane. For example, if I click anywhere on the Progress property, I’ll cause the track to start playing from that position. The same is true for the Volume property. If I click the Mute checkbox it will, of course, mute the audio. If I wanted to do everything I just described with an automation it would look like this:

with Home.House.First.Kitchen.KitchenMediaZone
  .Progress = 0.25
  .Volume = 0.80
  .Mute = true
end with

Now that we’ve had a brief introduction to Premise’s MediaZone, let’s look at two of its properties that would be useful in Home Assistant’s media_player.

PlayMode represents how the selected media should be played. The choices are:

  • NormalPlay. Play all selected media in order then stop.
  • ContinuousPlay. Play all selected media in order then repeat continuously.
  • RandomPlay. Play all selected media in random order.

Duration represents the playing time of the selected media. Home Assistant has this attribute but n Premise you don’t have to begin playing the media to determine its duration, you only have to select it for playing (‘load the track’).

There are other properties like Fade (fade between tracks) but they are device-dependent. Premise’s MediaZone object is one of the most complex of all of its objects. It has a core set of properties and methods but then others become available (or unavailable) depending on the actual capabilities of the physical media-playing devices.

On more thing … the Content property can be a single track, an album, a collection of albums (such as by an artist), or a playlist. I use the words track and album but the concept also apply to videos.

that s a mighty fine exposition, thanks for that. Why did you ever change to HA… :wink:

this would be my first hope… Think we have the RandomPlay in media_player.shuffle_set, but we certainly need the continuousPlay, as asked by me in feature request: media_player.play_loop

I didn’t.

I currently only use Home Assistant to provide a modern UI and for Homekit integration. Development of Premise ended in 2006 which, in terms of web UI technology, is aeons ago. Premise and Home Assistant communicate via MQTT.

I just added my vote for your feature request. Good luck!

1 Like

Not to revive an old topic, but is that gist still up to date with the latest versions of HA?

I’m impressed. That’s quite a wall of code. :wink:

I still need to weed thru to see how it’s all supposed to work tho and possibly adapt it as necessary.

I don’t think there were any breaking changes that would render it not usable but I think I have fine tuned a few things since then. My rPi died and it took me a while to get a replacement so I’ve been busy catching up (just updated from 92 something). I also went back to the normal format instead of packages, got tired of restarting testing all the changes…lol.

Let me know if your’re still interested and give me a day or so to pull together all the bits and I’ll repost whatever I have now. Happy to explain how it works. [deleted - I forgot I actually changed how it works, see posts below] Another neat little feature is the timer/counter combination to gradually increase the volume on regular intervals.

Yeah, thanks. I’m still interested.

I get what you mean about packages. I feel the same way but I just haven’t made the jump back yet. O don’t use them for a lot of stuff but they are still a great way to keep things organized for stuff like this.

Hey there sorry this took so long. I decided to finally get my config up on github and I had a bunch of stuff to clean up first. So tada - here it is. I’ve noticed you’ve been super active here in the forums. Your post on timestamps was great! If you’re bored and have time to poke around in my config a bit while you’re looking at the alarm clock stuff I’d love to hear what you think. My lovelace isn’t so pretty (I put up some screenshots) but it’s pretty functional and the back end is pretty solid now I think.

A couple of notes about the alarm clock (which along with the google mini on my night stand is really my alarm clock now!)

  • The “auto” alarm is triggered along with a bunch of other stuff by the wake up times set in the house schedule. It isn’t triggered anywhere in the alarm clock automations.

  • If HA is restarted while an alarm is set or active the alarm does actually restart but any timers get reset to their initial values.

  • The “sound loop” you are interested in is basically just a timer that restarts the alarm using the alarm sound MP3 file length as the timer duration. (My MP3’s are on github in the alarm_clock folder under /www.) That happens in script.alarm_clock_play with this code. I’m pretty sure this is what you are actually looking for.

      # start loop timer if alarm_clock_sound is not radio
      # player must start playing first to get media_duration
      - service_template: >-
          {% if not is_state('input_select.alarm_clock_sound', 'Radio') %} timer.start
          {% else %} script.null_script
          {% endif %}
        data_template:
          entity_id: timer.alarm_clock_restart
          duration:
            seconds: "{{ state_attr(states('sensor.alarm_clock_media_player'), 'media_duration') | round | int }}"

Anyway - you’ve helped out a lot of people on here so hopefully this helps you!

I should probably mention a couple of other things about the alarm clock so some of those automations make sense.

  • There are 3 alarm types - auto, manual, and nap. There are 2 modes to each alarm - on and active. On means the alarm is set, active means the alarm is playing. Auto alarms are triggered at times set in the house schedule automations. This was done because I work shift work so the alarm set time is automatically changed with my shift (which is automatically pulled from my Google calendar!). It also automatically changes the set time on weekends and work holidays. These set times are not available in the alarm clock because changing them changes so many other things in the house. The manual alarm is set in in alarm clock. It will fire every day at the set time if left turned on. Nap alarms are also set in the alarm clock, but will only fire once.

  • When an alarm first plays, it sends a push notification to our phones first. This way the alarm can be turned off or snoozed before it actually plays on the google mini so the wife doesn’t have to get woken up if I catch the notification on the phone first. The alarm will sound 1 minute later if I don’t respond or just close the notification.

  • Physically pausing the media player activates the snooze function. This will happen indefinitely. To turn the current alarm off (but not “disable”) you can either click the button in the push notification, click the alarm in any HA interface, say “Good Morning” or “I Am Awake” to google assistant, or grab the mini and toss it across the room and jump on it a few times (this actually works because if the media player goes unavailable the alarm in HA will actually turn off…lol). I thought about getting a little zwave button for the night stand to do this with but the voice option works so well it hasn’t been really necessary.

  • The state of the media player the alarm is set to play on is monitored and a push notification is sent if the media player becomes available. This has already come in very handy when my wife accidentally unplugged the mini when she was cleaning.

  • After a couple of minutes if the alarm is not playing when it should be, a push notification is sent and a TTS announcement plays on the announcement media players in the house (if they are still available) hopefully to still wake you or someone else in the house up.

  • There is a small logic error where if a nap alarm has been set and an auto or manual alarm plays before the nap alarm plays, the nap alarm will be cancelled when the other alarm is turned off. Very small chance of this every happening so I haven’t dug into it yet.

  • Two alarms can actually play at the same time as long as they are different types and are set to different media players. I thought about trying give each user their own alarm clock but that would mean basically doubling the code and trying to manage conflicts between them My wife and I work the same schedule so it’s not a priority for me. If you have any thoughts on how to easily accomplish this to make the alarm more useful lay 'em on me! I have the same kind issue with my streaming radio “app” (which you should also check out - it’s free, works great, and doesn’t require any accounts anywhere!).

  • Oh yeah, and the alarm clock volume automatically gets turned up every few minutes too.

1 Like

This is how the alarm looks when it’s playing in lovelace.

This is the push notification the alarm sends.

Capture

thanks again!

I’ll definitely check it all out.

@jazzyisj Where did you get the idea / code for your alarm clock? I love it, but tldr; I am lazy, and have had quite a difficult time sifting through the includes, scripts, and button layouts on your github

It’s all custom code. I needed an alarm clock that automatically changed with my work shifts. It’s also changed a bit since those screenshots were taken (it was 4 years ago!) What part are you having difficulty figuring out? If you’re just looking for a basic alarm clock it could be simplified quite a bit.

The meat and potatoes of it all (automations and scripts) are in these two folders and this package.

The front end is split up quite a bit as you probably discovered. But it shouldn’t be difficult to find them from the !include file paths. I would start with the alarm clock cards and go from there. There’s nothing overly complicated in there. Here’s a current screen shot.

image

No wonder it was giving me a headache trying to sift through. I really like the layout and options you have for the example prior … I guess Ill have to do my best to figure out how you did it. Mostly I am interested in the alarm sound and how you have chosen the radio station

I use Music Assistant now for most of my audio stuff. Unfortunately there isn’t a way to automatically populate a select with your playlists yet so I just made my own template to select playlists. The alarm “sounds” are actually a separate template which does auto populate when files are added or removed from the directory.

You could probably find the old layout by browsing through my git history. I think this would be close to the screenshot you’re interested in, unfortunately much of it is not usable as things have changed so much since then.

1 Like

Looks like I still have a lot to learn. I haven’t been doing this for very long, maybe about a year… maybe. Thanks for the pointers and links, I’m still finding new things to do everyday, and losing hair with them too (ok well maybe not but it feels like it)