How to figure out the length of a local media file?

Hello to everyone,

I have an automation for voice announcements to a media player. There are two service calls (media_player.play_media). First, plays a chime, which is different depending on the type of the message. The second, is a TTS message. Both service calls are performed as announcements in order not to stop the music if playing.

The problem is when you make these service calls one after another the second one interrupts the first one (the chime). So it would be wise to put a templated delay between them which would be equal to the length of the chime sent in the first service call.

Can anyone hint on a workaround to figure out the length of a locally stored audio media file?

You should include your automation YAML. There is probably a better way to do this without a delay.

Here is the basic example of what I mean:

description: "Test"
mode: single
trigger:
  - platform: state
    entity_id:
      - input_boolean.test_switch
    to: "on"
condition: []
action:
  - service: media_player.play_media
    metadata: {}
    data:
      announce: true
      media_content_id: >-
        media-source://media_source/media/Announcements/Chimes/hd_message_tone.mp3
      media_content_type: music
    target:
      entity_id: media_player.comedor
  - delay:
      hours: 0
      minutes: 0
      seconds: 3
      milliseconds: 0
  - service: media_player.play_media
    metadata: {}
    data:
      announce: true
      media_content_id: media-source://tts/tts.google_en_com?message=Hello!
      media_content_type: music
    target:
      entity_id: media_player.comedor

Here’s one way that works:

  - delay: >-
      {% set duration = (states.media_player.comedor.attributes.media_duration) %}
      {% if duration < 2 %}
        {% set duration = 2 %}
      {% endif %}
      {% set seconds = duration % 60 %}
      {% set minutes = (duration / 60)|int % 60 %}
      {% set hours = (duration / 3600)|int %}
      {{ [hours, minutes, seconds]|join(':') }}

Just paste it in your code where you would normally use the delay and remember to use the correct name for your media player. You can remove the IF statement if you don’t need a minimum time of 2 seconds.

  • Edited with your media player correctly inserted.

If this works for you, please mark it as the solution so that others may also benefit.

This is great! I confirm this works if no music is currently playing.
However, if music is playing when you call the service media_player.play_media it will count the length of the music playing and not the one of the chime.

But thank you very much! This is still much better than nothing.

Hope there is a way to count the length of the media that is being sent as an announcement.

The exact problem you’re describing is solved with the Chime TTS integration.

1 Like

That is exactly what I was looking for. It makes the whole process some much faster and easier.
Thank you very much!