From 49316a7981f0cc74c560ee6fcb2208d5b6eddda0 Mon Sep 17 00:00:00 2001 From: Loren Moore Date: Sun, 14 Aug 2022 22:15:48 -0400 Subject: [PATCH] Fix cartplayer extension fallthrough. Add HOWTHISWORKS.MD. Added ajw.sh --- HOWITWORKS.MD | 131 +++++++++++++++++++++++++++++++++++++++++++ README.md | 71 ++++++----------------- ajw.sh | 57 +++++++++++++++++++ tapecart-player.conf | 13 ++++- 4 files changed, 215 insertions(+), 57 deletions(-) create mode 100644 HOWITWORKS.MD create mode 100644 ajw.sh diff --git a/HOWITWORKS.MD b/HOWITWORKS.MD new file mode 100644 index 0000000..5561aae --- /dev/null +++ b/HOWITWORKS.MD @@ -0,0 +1,131 @@ +# Asterisk Jukebox Theory of Operation & Explanation + +## Welcome + +This document will hopefully demystify just what an Asterisk Jukebox is and how it works. If you haven't guessed by the fact it's called a jukebox it plays music, +specially it can play full albums or a single track from an album in an almost-automatic fashion based on DTMF input from a user. + +## Basic Explanation + +The user dials the jukebox. They then punch in a 4 digit number; this corresponds to a format of the first two digits being the album, and last two being track number. +The user can enter a special track number of 00 to play a full album. Playback is controlled entirely through dialplan logic in a mostly automatic fashion; it increments +through tracks using a counter and ends when it hits the total number of tracks. This information is passed to the playback context from a setup context. These are placed +into to two files: + +- tapecart-player.conf: Contains the playback logic shared among all jukeboxes. (It's the playback mechanism) +- $name-main.conf: Contains the dialplan to setup tapecart-player to play. (It stacks the records and hits play) + +In order for this to work it requires you to not just pre-encode your files to a compatible format; but it also requires to you stick to a pre-set folder/filename convention. +This...conveniently...is simply jukeboxroot/albumfolder/(0)1-99.ulaw. The dialplan logic can be set to handle leading 0s for files under 10. + +To aid in creation of a jukebox; the ajw.sh script will generate these for you given just a few options. + +### #name-main.conf + +The configuration context can be in a sperate file included in your extensions.conf; or copy pasted in to your extensions.conf. The main point is that Asterisk knows where to find +the context for configuration as well as the two for playback. These can be generated by hand, if you want; the copy/paste format is easy enough to do. But for large jukeboxes it +can get tedious, hence a script. + +``` +[examplejuke-main] +exten = s,1,Answer() # Answer the channel. +same = n,Set(VOLUME(TX)=-3) # Lower volume since that seems necessary. +same = n,Set(c=examplejuke-main) # Set the "c" variable so we can return to this context. +same = n(loop),Background(foobar/menu) # Label for "loop", plays the menu audio. +same = n,WaitExten(5) # Wait a few seconds +same = n,Set(m=$[${m} + 1]) # Increase "m" by one. +same = n,GoToIf($["${m}" < "5"]?loop) # Compare to "5", return to "loop" if true. +same = n,(goodbye)Background(foobar/bye) # It was false...good bye. "Goodbye" label. +same = n,Hangup() # SLAM + +exten = _00XX,1,Set(aa=foobar/00album) # Set the aa variable to the album directory for leading 00 +same = n,GoToIf($["${EXTEN:-2}" = "00"]?8track-player,*11,1) # Check last two dialed. If album playback, pass total tracks as extension. +same = n,GoTo(cart-player,*${EXTEN:-2},1) # Pass the last two digits to cart-player as *ext + +exten = _01XX,1,Set(aa=foobar/01album) # Repeat for album leading 01 +same = n,GoToIf($["${EXTEN:-2}" = "00"]?8track-player,*15,1) +same = n,GoTo(cart-player,*${EXTEN:-2},1) + +exten = _02XX,1,Set(aa=foobar/02album) # Album 02 is different. Files do not have a leading 0. +same = n,GoToIf($["${EXTEN:-2}" = "00"]?8track-player,#12,1) # Pass last two to 8track-player's # pattern. +same = n,GoToIf($["${EXTEN:-2}" < "10"]?cart-player,#${EXTEN:-1},1) # If the last two are less than 10; pass to single digit to cart-player #ext +same = n,GoTo(cart-player,*${EXTEN:-2},1) # Use the "standard" call for tracks more than 10. +``` + +The setup for the jukeboxes has undergone about as much optimization as I think I can perform. I did trade a few variables for reducing the overall number of lines. +The need to set the home context is due to all the playback logic not being in the same context. The use of WhileLoops was eliminated entirely due to problems with +the inability to pop cleanly out of a loop. I was also looking to reduce how much you had to create for each jukebox; which allowed the script to do more automated +stuff like automagically counting albums, tracks, and leading zeros. They used to be twice the lines because I was setting total tracks to a variable. + + +### cart-player and 8track-player + +Both of these live in a single file, tapecart-player.conf. They were not designed to be modified by a user and were designed to simply be included in such a way that +your jukebox dialplans can see them. It seemed stupid to constantly rewrite these playback routines every time. In fact I later went through and redid early pre-juke +album setups to use this same logic. Provided you can work with the requirement of number-only filenames it can be handy. + +``` +[cart-player] +exten = _#X,1,Wait(.25) # The # extensions are for non-leading zeros. Give DTMF time to shut-up. +same = n,Set(z=${EXTEN}) # Write extension to variable for recall later. +same= n,Background(${aa}/${EXTEN:-1}) # Pass the last digit as the file name to be played. (1.ulaw, 9.ulaw) +same = n,Goto(${c},s,return) # It's done. Go home. +exten = _*XX,1,Wait(.25) # All tracks over 10 or with leading zeros. Shut up DTMF. +same = n,Set(z=${EXTEN}) # Write extension to variable for recall later. +same= n,Background(${aa}/${EXTEN:-2}) # Pass last two of extension (the only two) as filename (01.ulaw ... 99.ulaw) +same = n,Goto(${c},s,return) # It's done. Go Home +exten = 2,1,Goto(cart-player,${z},1) # Start the song over. +exten = i,1,Goto(${c},s,return) # Press anything but 2 to go away at any time. + +[8track-player] +exten = _*XX,1,Set(tt=${IF($[${EXTEN:-2} < 10]?${EXTEN:-1}:${EXTEN:-2})}) # Leading zeros. Check if album is less than 10 tracks. Set tt (total tracks). +same = n,Set(t=1) # Initialize track counter. +same = n,Set(p=*) # Set context prefix for controls use. +same = n(lead),GoToIf($[${t} = 10]?tenplus) # If we've crossed track 10, jump to "tenplus". Label for "lead". +same = n(hax),Background(${aa}/0${t}) # Prefix 0 to filename based on "t" for leading zeros. "hax" label. +same = n(next),Set(t=$[${t} + 1]) # "next" label. Increases track counter by one. +same = n,GoToIf($[${t} < ${tt}]?lead) # Compares track count to TT value. Loops back to "lead" if not met. +same = n,Goto(${c},s,goodbye) # We played all the tracks. Go back to main menu "goodbye". +same = n(tenplus),Set(p=#) # "tenplus" label. Change p from * to #. +same = n,GoTo(#00,hax) # Switch to the "hax" prority for #00 to continue double-digit file playback. +exten = _#XX,1,Set(tt=${IF($[${EXTEN:-2} < 10]?${EXTEN:-1}:${EXTEN:-2})}) # No Leading zero filenames. Checks for albums less than 10. Sets tt. +same = n,Set(t=1) # Initializes playback counter +same = n,Set(p=#) # Sets the P variable +same = n(hax),Background(${aa}/${t}) # Plays back file. Hax label. Entry point from * land. +same = n(next),Set(t=$[${t} + 1]) # Increase track count +same = n,GoToIf($[${t} < ${tt}]?hax) # Look at track count compared to total. Go back to hax if not done. +same = n,Goto(${c},s,goodbye) # Done. Stop wasting my money/ + +exten = 1,1,GoToIf($["${t}" = "1"]?wait) # Track back. Check to see if we can go back. Just skip if we can't. +same = n,Set(t=$[${t} - 1]) # Subtract 1 from T. +same = n(wait),Wait(.25) # Wait for DTMF to shut up. +same = n,Goto(${p}00,hax) # Go back from whatever extension branch we were one based on p to the hax label. +exten = 2,1,Wait(.25) # Wait. +same = n,Goto(${p}00,hax) # Just loop back to hax without changing track count. +exten = 3,1,Wait(.25) # Wait. +same = n,Goto(${p}00,next) # Jump to "next" in wherever the hell we are. +exten = 0,1,Goto(${c},s,return) # Press 0 to go home. +``` + +So the basic idea is that these dialplans either play back a single file, or play back an album. They do so without manaually coding a list of files by relying on the files to be +organized and named a specific way; then just using the basic logic functions of the dialplan. Name your files to track numbers; use a variable to count tracks; tell the program +to play the file that matches the number in the variable. Repeat this until you hit the end of the tracks. + +The reality is you also have to tell it how many tracks you have and deal with a little issue of leading zeros. Here's the leading 0 issue in a nutshell: + +- My files are name 01.ulaw, 02.ulaw, 03.ulaw, etc... +- I set T as 01 manually. Asterisk plays 01.ulaw. +- Track ends. Dialplan adds one to T. +- T is now 2. 2 != 02. + +So why was this a problem? Why not just drop the leading zeros from the file name? Because I knew either way I'd have to add some logic. What I should have done is set the dialplans +to require # for entry; this would have allowed me to do 3 or 4 digit entries and not have any additional logic; other than the extra pattern matching. IF I kept the 4 digit entry, +I'd have to add logic to check for tracks less than 10 so i write the file variable properly. The logical solution was to add the extra logic and make it flexible. The script that +writes the jukebox dialplans handles whether or not we call a leading 0 extension. I wind up adding about the same amount of code for a fix but gain more in it's flexibility. In fact +the "hax" label was an early hold-over from testing the leading 0 routine; originally the playback routines were hard-coded in the jukebox dialplan. + +Though we call specific extensions in the context; once we're in we don't. The number you pass as an extension just configures the number of tracks. Once we have that, we don't need +it. This is why the playback controls and "over 10" make a call to double-0...specifically double-zero hax label. We just need to get back in to the proper set of logic. Calling ext +00 from outside the playback context would likely result in the first file playing and then ending immedately. In fact...brainstorm. Pass the number of tracks and track selection as +a four digit extension. Set number of tracks to 00 with track number to get single track playback; pass number of tracks with track number 00 to play an album. That might be the next +major revision to the asterisk jukebox if I can figure out how to handle the leading 0 BS. \ No newline at end of file diff --git a/README.md b/README.md index 3cd1bcc..c440b4f 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ as logic to perform this playback. Asterisk Jukebox & Player consist of two basic dialplans: -``` -a common set of logic for playback called from a jukebox interface -a jukebox interface dialplan for music/album selection -``` + +- a common set of logic for playback called from a jukebox interface +- a jukebox interface dialplan for music/album selection + There is no reason you cannot use the player outside of a jukebox, provided you set all the variables and call the proper extensions in it's context. @@ -49,14 +49,14 @@ extensions.conf. tapecart-player.conf provides two contexts: -[cart-player] - provides single track playback -[8track-player] - provides album playback +- [cart-player] - provides single track playback +- [8track-player] - provides album playback For both contexts, the following variables will need to be set before sending a channel to them: -c - the context you are sending from (used for returning from player) -aa - the path relative to your asterisk sounds directory your files live. +- c - the context you are sending from (used for returning from player) +- aa - the path relative to your asterisk sounds directory your files live. Both contexts use pattern matching extensions to select behavior as well as pass information. @@ -81,6 +81,8 @@ which is not equal to "02" and causes playback to fail. Some of the logic for cart-player is done at the jukebox dialplan for dealing with lack of leading zeros; because sometimes you EXTEN:-2 and sometimes you want to EXTEN:-1. +The ajw.sh script will generate the configuration dialplans for you. + ## Using The Jukebox @@ -96,9 +98,9 @@ to enter a 4 digit code comprised of the album and track number: Track number "00" is special and when entered, will play the entire album back from the beginning. In album playback, the following controls affect playback: -1 - skips back a track -2 - repeats the current track -3 - skips ahead a track +- 1 - skips back a track +- 2 - repeats the current track +- 3 - skips ahead a track At the end of the album, or at any time during playback; pressing 0 returns to the main menu. @@ -109,55 +111,14 @@ pressing 0. # History ``` -05-MAY-2022: Initial Commit to self-hosted git. +14-AUG-2022: Fix cartplayer extension fallthrough. Add HOWTHISWORKS.MD. Added ajw.sh 06-MAY-2022: Update Readme. Add conf/examples. - +05-MAY-2022: Initial Commit to self-hosted git. ``` # Explanation of Operation -Rather than just write a script to generate a massively large dialplan with -everything hard-coded; the playback logic was designed to be universal and -uses extensions to configure parts of it. - -From your jukebox dialplan, the first two digits of entry are hard-coded and -set the folder location for those tracks. The last two digits are pattern -matched. If they're 00, it calls the appropiate extension 8track-player. -Otherwise it calls the proper extension for cart-player; using additional -logic for leading 0s. - -For single track playback (cart-player context), two pattern matching -extensions are used: - -``` -#X - with X being 1 - 9 for files without leading zeros -*XX - with XX being all tracks > 10 or with leading zeros -``` -The only difference between them is how many digits you send and how many it -pulls from the "dialed extension". Pound and asterisk are used as a pre-fix to -avoid conflict with 1,2,3, and 0 controls. - -For album playback, the situation is quite similar: - -``` -#XX - with XX being the number of tracks plus one. files without leading 0. -*XX - with XX being the same as above, but files with leading 0. -``` - -When you call the aprpropiate extension, the player determines if the track -number is less than 10 so it can write that variable appropiately. It then sets -a variable to either `#` or `*`, depending which was used. This variable is -used for the playback controls. - -If your files don't have the leading zero (sent to #), then the routine simply -plays a track, increments the counter, compares it to the track count, and then -sends it back to playback or not. For channels sent to \* because you have -leading zeros, a few additional steps are done. Rather than jump directly to -playback; we check to see if current track has hit ten. If not, continue as -usual. But when you do hit track 10, we jump to a couple of lines that change -the varible from pound to star, and then dump us in to the context at normal -playback. We then finish the remainder of the album looping through the pound -extension. +A full breakdown is in HOWTHISWORKS.MD diff --git a/ajw.sh b/ajw.sh new file mode 100644 index 0000000..935c42a --- /dev/null +++ b/ajw.sh @@ -0,0 +1,57 @@ +#!/bin/bash +#ajw v1.02 - jukebox for asterisk wizard +#Jay Moore/NQ4T - https://git.pickmy.org/dewdude/ajw +#Twitter: @Music_OnHold +#Licensed under GPL-3.0-or-later + +# Works like this: +# Put all your albums in your Asterisk sounds directory: /jukebox root/album/track#.ulaw +# Run script, enter prompts. +# Copy .conf, include in extensions.conf, assign extension. + +setup() { +printf "[$name-main]\nexten = s,1,Answer()\nsame =n,Set(VOLUME(TX)=$vol)\nsame = n,Set(c=$name-main)\nsame = n(return),Set(m=1)\nsame = n(loop),Background($rootfolder/$introfile)\n" +[ "$delay" -ne 0 ] printf "same = n,WaitExten($delay)\n" +printf "same = n,Set(m=\$[\${m} + 1])\nsame = n,GoToIf(\$[\"\${m}\" > \"$loop\"]?loop)\nsame = n(goodbye),Background($rootfolder/$goodbye)\nsame = n,Hangup()\n\n" +} >> $name-juke.conf + +album() { +printf "exten = _%02dXX,1,Set(aa=$rootfolder/$folder)\n" $a +[ "$lz" -eq 0 ] && printf "same = n,GoToIf(\$[\"\${EXTEN:-2}\" = \"00\"]?8track-player,#$tc,1)\n" || printf "same = n,GoToIf(\$[\"\${EXTEN:-2}\" = \"00\"]?8track-player,*$tc,1)\n" +[ "$lz" -eq 0 ] && printf "same = n,GoToIf(\$[\"\${EXTEN:-2}\" < \"10\"]?cart-player,#\${EXTEN:-1},1)\n" +printf "same = n,GoTo(cart-player,*\${EXTEN:-2},1)\n\n" +} >> $name-juke.conf + +printf "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n |a|j|w| - asterisk jukebox wizard\n version 1.02 - Jay Moore/NQ4T\n https://git.pickmy.org/dewdude/jaw\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n\n\n" +printf "Pick a name/identifier for this jukebox: " +read name +printf "\nEnter the root folder name of your jukebox: " +read rootfolder +printf "\nEnter the filename of your menu/intro: " +read introfile +printf "\nHow many times do you want it to play? " +read loop +printf "\nHow many seconds between intro play? (Enter 0 for no delay)" +read delay +printf "\nEnter the filename of your exit file: " +read goodbye +printf "\nEnter a channel volume (I recommend -3): " +read vol +printf "\nWriting Basic Configuration.\n\nAuto-Generating Albums\n\n" +setup; +asd=/var/lib/asterisk/sounds/en/astjuke +dir=$(ls $asd/$rootfolder -l | awk '/^d/ {print $9}') +a=0 +for folder in $dir +do +tracks=$(ls $asd/$rootfolder/$folder -l | grep "ulaw" | wc -l) +tracks=$((tracks + 1)) +tc=$(printf "%02d" $tracks) +ld=$(ls $asd/$rootfolder/$folder -l | grep "ulaw" | awk '{print $9}' | awk '/^0/') +[ -z "$ld" ] && lz=0 || lz=1 +album; +a=$((a + 1)) +done + +printf "\n\nDone.\n\n\nYour jukebox is located at $name-juke.conf.\n" +printf "Make sure to include it and the player conf in your dial plan somewhere.\n\n\n\n" \ No newline at end of file diff --git a/tapecart-player.conf b/tapecart-player.conf index a37d9fe..a4afdd6 100644 --- a/tapecart-player.conf +++ b/tapecart-player.conf @@ -1,11 +1,20 @@ +;tapeplayer.conf - Asterisk Jukebox - Version 1.something +;Jay Moore - NQ4T - Twitter: @Music_OnHold +;https://git.pickmy.org/dewdude/Asterisk_Jukebox +;https://git.pickmy.org/dewdude/ajw + [cart-player] exten = _#X,1,Wait(.25) -same= n,Background(${aa}/${EXTEN:-1}) +same = n,Set(z=${EXTEN}) +same= n(replay),Background(${aa}/${EXTEN:-1}) same = n,Goto(${c},s,return) exten = _*XX,1,Wait(.25) +same = n,Set(z=${EXTEN}) same= n,Background(${aa}/${EXTEN:-2}) same = n,Goto(${c},s,return) -exten = 0,1,Goto(${c},s,return) +exten = i,1,Goto(${c},s,return) +exten = 2,1,Goto(cart-player,${z},1) + [8track-player] exten = _*XX,1,Set(tt=${IF($[${EXTEN:-2} < 10]?${EXTEN:-1}:${EXTEN:-2})})