Channel Collection Logos

OK, in that case, you can try this modification to generatem3u.sh:

Find the line in the outputCollectionM3U() function, and comment it out like so:

  #allChannelsM3U=$(curl $m3uURL)

And add the following below it:

  allChannelsM3U=$(curl http://$dvr/devices/ANY/channels)

Then, do the same with this combination:

    #collectionChannelM3U=$(echo "$allChannelsM3U" | grep -A 1 -E "tvg-chno=\"$collectionChannelNumber\"")

Adding the following below:

    collectionChannelM3U=$(echo "$allChannelsM3U" | jq -r '.[] | select(.GuideNumber == "'"$collectionChannelNumber"'") | "#EXTINF:-1 channel-id=\"\(.GuideNumber)\" tvg-id=\"\(.GuideNumber)\" tvg-chno=\"\(.GuideNumber)\" tvg-logo=\"\(.Logo)\" tvc-guide-stationid=\"\(.Station)\" tvg-name=\"\(.GuideName)\",\(.GuideName)\nhttp://'$dvr'/devices/ANY/channels/\(.GuideNumber)/hls/master.m3u8?"')

The re-run the M3U generation as before, and see if the result is what you're after.

I am sorry do I do this in olivetin??

The script can be found in the directory you have bound to /config in this section of your OliveTin docker-compose:

    volumes:
      - ${HOST_DIR}/olivetin:/config # Add the parent directory on your Docker host you'd like to use

EDIT: If you feel like this is too far outside your wheelhouse, don't worry about it -- I can build you a container with the :test tag tomorrow and we can try it that way.

Yes, I am not understanding because the way I setup Olivetin for channels was going to my container manager, and pulling the image and creating a container with it. Thank you!!


@mexicanmamba Well, I had to chase down a couple of issues with my build system, but all is well now -- and, I've built the promised container for you with the :test tag.

I do see an issue moving forward though, as you haven't used Portainer (a stated requirement for this project) to spin-up OliveTin-for-Channels. I think you'd find it to be a better, and more complete, tool than the Synology Container Manager.

I'm only supporting this project via Portainer, as there are already enough variables to deal with related to people's individual setups without adding additional complication. Though I'm not a Synology user, it looks pretty clear to me that you haven't set up your docker volumes correctly, as there's no directory on your Synology bound to /config in the container. This would result in none of your data being persistent, or easily accessible on your host.

Without the complete docker-compose used, and appropriate environment variables defined, it'll be hit-or-miss on whether a particular OliveTin Action will function correctly.

I was able to find a solution, I uploaded my own logos for the channels I deemed necessary that needed an update. Channel mapping and new logos, its like I have cable again thank you again for your assistance!!

This doesn't help me much -- did you try the new container I built for you? If so, did it work?

Yes I was indeed able to rebuild a new container with the yaml compose. Once I built a new docker the channels were indeed exported along with the M3U in Olivetin.

And did the M3U generated by OliveTin contain your desired logos?

Yes, I was able to update a few channels like NBC News Now and ABC News Live.

If I'm understanding you correctly then, most of the logos where generated as you wanted them to be -- but you changed a few manually. And, I'm guessing this is because they weren't as you wanted them in the Channels Source? Nothing to do with OliveTin?

Correct, I thought it was at first an olivetin issue but it was an issue with the way I configured Olivetin in my NAS.

OK, great -- glad it worked out for you. I'll push that same code in a container with the :latest tag in the next few days, and delete :test.

3 Likes

If anyone wants to add their own logos, here are some cool retro ones.

Didn't make it into :latest ?
It's still parsing http://$dvr/devices/$source/channels.m3u instead of http://$dvr/devices/$source/channels so not getting the Fubo logos

No, but I should be pushing it tomorrow with the latest @mjitkop work.

If you want to test the changes here's the updated outputCollectionM3U() function from generatem3u.sh -- and you'll see there are only two lines changed. The line below each commented-out line is its replacement:

outputCollectionM3U() {
  collectionChannelIDs=$(curl http://$dvr/dvr/collections/channels | jq -r '.[] | select(.name == "'"$collection"'") | .items[]')
    [[ -z $collectionChannelIDs ]] \
    && echo "Channel Collection not found: $collection" \
    && exit 1
  echo -e "M3U for Collection: $collection\nSource M3U used: $m3uURL\nCopy & Paste M3U from here or use: $m3uFile\n" > $logFile
  [[ -n $duration ]] && echo -e "Optional guide data URL: http://$dvr/devices/$source/guide/xmltv?duration=$duration\n"
    allChannelsJSON=$(curl http://$dvr/devices/ANY/guide/now)
  #allChannelsM3U=$(curl $m3uURL)
  allChannelsM3U=$(curl http://$dvr/devices/ANY/channels)
  echo -e "#EXTM3U\n" > $m3uFile

  for collectionChannelID in ${collectionChannelIDs[@]}; do
    collectionChannelNumber=$(echo "$allChannelsJSON" | jq -r '.[] | select(.Channel.ChannelID == "'"$collectionChannelID"'") | .Channel.Number')
    #collectionChannelM3U=$(echo "$allChannelsM3U" | grep -A 1 -E "tvg-chno=\"$collectionChannelNumber\"")
    collectionChannelM3U=$(echo "$allChannelsM3U" | jq -r '.[] | select(.GuideNumber == "'"$collectionChannelNumber"'") | "#EXTINF:-1 channel-id=\"\(.GuideNumber)\" tvg-id=\"\(.GuideNumber)\" tvg-chno=\"\(.GuideNumber)\" tvg-logo=\"\(.Logo)\" tvc-guide-stationid=\"\(.Station)\" tvg-name=\"\(.GuideName)\",\(.GuideName)\nhttp://'$dvr'/devices/ANY/channels/\(.GuideNumber)/'$streamURL'"')
    [[ -n $collectionChannelM3U ]] && echo -e "$collectionChannelM3U\n" >> $m3uFile
  done

  cat $m3uFile >> $logFile
  cat $logFile
}

@chDVRuser

Scratch the above, I forgot I added another function too, so here's the whole updated generatem3u.sh:

#!/bin/bash

#set -x

dvr=$1
channelsHost=$(echo $dvr | awk -F: '{print $1}')
channelsPort=$(echo $dvr | awk -F: '{print $2}')
logFile=/config/"$channelsHost"-"$channelsPort"_generatem3u_latest.log
source=$2
collection=$3
  [[ "$collection" == "none" ]] && collection=""
bitrate=$4
  [[ "$bitrate" == "none" ]] && bitrate="" || bitrate=$(echo "bitrate=$bitrate")
  [[ "$bitrate" == "bitrate=copy" ]] && bitrate="codec=copy"
filter=$5
  [[ "$filter" == "none" ]] && filter="" || filter=$(echo "filter=$filter")
format=$6
  [[ "$format" == "hls" ]] && format="" || format=$(echo "format=$format")
abr=$7
  [[ "$abr" == "true" ]] && abr="" || abr=$(echo "abr=$abr")
duration=$8
  [[ "$duration" == "none" ]] && duration=""
m3uFolder=/config/data && mkdir -p $m3uFolder
m3uFile="$m3uFolder"/"$channelsHost"-"$channelsPort".m3u

buildURL() {
  concatenator="?"
  m3uURL="http://$dvr/devices/$source/channels.m3u"
    [[ -n $bitrate ]] && m3uURL=$(echo "$m3uURL""$concatenator""$bitrate") && concatenator="&"
    [[ -n $filter ]] && m3uURL=$(echo "$m3uURL""$concatenator""$filter") && concatenator="&"
    [[ -n $format ]] && m3uURL=$(echo "$m3uURL""$concatenator""$format") && concatenator="&"
    [[ -n $abr ]] && m3uURL=$(echo "$m3uURL""$concatenator""$abr") && concatenator="&"
}

buildStreamURL() {
  concatenator="?"
  [[ -z $format ]] && streamURL="hls/master.m3u8" || streamURL="stream.mpg"
    [[ -n $bitrate ]] && streamURL=$(echo "$streamURL""$concatenator""$bitrate") && concatenator="&"
    [[ -n $filter ]] && streamURL=$(echo "$streamURL""$concatenator""$filter") && concatenator="&"
    [[ -n $format ]] && streamURL=$(echo "$streamURL""$concatenator""$format") && concatenator="&"
    [[ -n $abr ]] && streamURL=$(echo "$streamURL""$concatenator""$abr") && concatenator="&"
    [[ $concatenator == "?" ]] && streamURL=$(echo "$streamURL""$concatenator")
}

outputM3U() {
  echo -e "M3U used: $m3uURL\n" > $logFile
  [[ -n $duration ]] && echo -e "Optional guide data URL: http://$dvr/devices/$source/guide/xmltv?duration=$duration\n"
  curl $m3uURL > $m3uFile
  cat $m3uFile >> $logFile
  cat $logFile
}

outputCollectionM3U() {
  collectionChannelIDs=$(curl http://$dvr/dvr/collections/channels | jq -r '.[] | select(.name == "'"$collection"'") | .items[]')
    [[ -z $collectionChannelIDs ]] \
    && echo "Channel Collection not found: $collection" \
    && exit 1
  echo -e "M3U for Collection: $collection\nSource M3U used: $m3uURL\nCopy & Paste M3U from here or use: $m3uFile\n" > $logFile
  [[ -n $duration ]] && echo -e "Optional guide data URL: http://$dvr/devices/$source/guide/xmltv?duration=$duration\n"
    allChannelsJSON=$(curl http://$dvr/devices/ANY/guide/now)
  #allChannelsM3U=$(curl $m3uURL)
  allChannelsM3U=$(curl http://$dvr/devices/ANY/channels)
  echo -e "#EXTM3U\n" > $m3uFile

  for collectionChannelID in ${collectionChannelIDs[@]}; do
    collectionChannelNumber=$(echo "$allChannelsJSON" | jq -r '.[] | select(.Channel.ChannelID == "'"$collectionChannelID"'") | .Channel.Number')
    #collectionChannelM3U=$(echo "$allChannelsM3U" | grep -A 1 -E "tvg-chno=\"$collectionChannelNumber\"")
    collectionChannelM3U=$(echo "$allChannelsM3U" | jq -r '.[] | select(.GuideNumber == "'"$collectionChannelNumber"'") | "#EXTINF:-1 channel-id=\"\(.GuideNumber)\" tvg-id=\"\(.GuideNumber)\" tvg-chno=\"\(.GuideNumber)\" tvg-logo=\"\(.Logo)\" tvc-guide-stationid=\"\(.Station)\" tvg-name=\"\(.GuideName)\",\(.GuideName)\nhttp://'$dvr'/devices/ANY/channels/\(.GuideNumber)/'$streamURL'"')
    [[ -n $collectionChannelM3U ]] && echo -e "$collectionChannelM3U\n" >> $m3uFile
  done

  cat $m3uFile >> $logFile
  cat $logFile
}

main() {
  buildURL
  [[ -n $collection ]] && buildStreamURL
  [[ -z $collection ]] && outputM3U || outputCollectionM3U
}

main

Excellent. I see you increased the timeout in your latest release for that action in config.yaml to 180.
If a user has multiple sources, it can take awhile.
I'm running the dvr in a container in host network mode and it sees my HDHR Prime as a device, even though it's not assigned guide data. So it runs through every channel on it in http://$dvr/devices/$source/channels since I have to leave source ANY when doing a channel collection m3u. Taking 80-140 seconds to generate the m3u.