Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
agmark
Visitor

Question on parsing mp3 and mp4

I'm attempting to use the mrss template channel to parse either an audio rss feed or a video rss feed depending on the catagory the user selects. The video items play fine as is, and if I change the streamFormat: from "mp4" to "mp3" the audio plays ok. What would be an efficient code to set the "streamFormat"? The code section below is from the NWM_MRSS.brs file.

xml = CreateObject("roXMLElement")
if xml.Parse(raw)
for each item in xml.channel.item
newItem = {
streams: []
'streamFormat: "mp4"
streamFormat: "mp3"
actors: []
categories: []
contentType: "episode"
}


The url is being pulled from the following example line in the XML feed:
<enclosure url="http://my.mediafile.com/song.mp3" length="23910262" type="audio/mpeg" />


The video files have a type of
type="video/quicktime"


I'm sure it's not too complicated, but I'm still learning the basics. Also, I'm assuming the contentType should be changed too, but it doesn't affect the ability for the audio to play.
TIA
~Mark
0 Kudos
8 REPLIES 8
agmark
Visitor

Re: Question on parsing mp3 and mp4

Here's what I've tried, but I'm not coding it correctly. Can someone help me correct the code below? I'm getting a type Mismatch at line
 if newFormat = "audio/mpeg" 

I changed the
streamFormat: "mp4" to streamFormat: [] and then added the code section below to parse the file type and then insert the correct file extension in the array.

if item.enclosure.Count() > 0
newFormat = {
url: ValidStr(item.enclosure@type)
}

if newFormat = "audio/mpeg"
fileFormat = "mp3"
else if newFormat = "video/quicktime"
fileFormat = "mp4"
end if

newItem.streamFormat.Push(fileFormat)
result.Push(newItem)


end if


I know it's not right but I'm not sure what the correct format should be. Any help?
TIA
0 Kudos
belltown
Roku Guru

Re: Question on parsing mp3 and mp4

newFormat is an associative array, not a string. You need to select the url property of the associative array, which should be a string:

if newFormat.url = "audio/mpeg" 
0 Kudos
agmark
Visitor

Re: Question on parsing mp3 and mp4

Thanks belltown. I couldn't make that approach work so I tried this. It appears to work although I haven't had a chance to completely test it. It apparently set the streamFormat array with the correct mp3 format. I could successfully stream an audio feed. Just need to check if it's successful when I add videos. I also need to work on the "else" statement to handle any other type of files found in the feed. I see a couple pdf files in the rss feed I'm parsing so I'll need to ignore those. Does anyone see any obvious problems with the code below?


' streamFormat
if item.enclosure.count() > 0
for each enclosure in item.enclosure

if item.enclosure@type = "audio/mpeg"
fileFormat = "mp3"
else if item.enclosure@type = "video/quicktime"
fileFormat = "mp4"
else fileFormat = ""
end if

newItem.streamFormat = fileFormat
next
end if
0 Kudos
belltown
Roku Guru

Re: Question on parsing mp3 and mp4

else fileFormat = "" should be: else if fileFormat = ""

and

next should be: end for
0 Kudos
TheEndless
Channel Surfer

Re: Question on parsing mp3 and mp4

"belltown" wrote:
next should be: end for

FYI, "Next" and "End For" are interchangeable in BrightScript.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
belltown
Roku Guru

Re: Question on parsing mp3 and mp4

"TheEndless" wrote:
"belltown" wrote:
next should be: end for

FYI, "Next" and "End For" are interchangeable in BrightScript.


Thanks for clarifying that. I didn't see any reference to "next" in the BrightScript 3.0 Reference, except as a reserved word, so I figured if it worked it was an undocumented feature and probably not as safe to use as the documented "end for".
0 Kudos
uarlive
Visitor

Re: Question on parsing mp3 and mp4

First of all thanks for this post. it has been extremely helpful. I am looking to add the roaudioplayer functionality into this template. From my logic I am thinking I need to invoke a function call off the results of the streamformat

' streamFormat
if item.enclosure.count() > 0
for each enclosure in item.enclosure

if item.enclosure@type = "audio/mpeg"
fileFormat = "mp3"


Then invoke a function which creates a separate roaudioplayer call and loads the springboard . Is my logic correct?

Thanks.
0 Kudos
belltown
Roku Guru

Re: Question on parsing mp3 and mp4

Here's one way to adapt the MRSS template to play mp3 audio files. This was tested using the old 1.1.1 MRSS template rather than the one in the 4.1 SDK which seems to be buggy (several duplicate functions defined).

Step 1, edit the config.opml file to include a feed that contains mp3 audio. For example, I added the Tech Report podcast feed at the end:


<?xml version="1.0" encoding="ISO-8859-1"?>
<opml version="1.0">
<body
backgroundColor="#444444"
leftBreadcrumbColor="#00EE00"
rightBreadcrumbColor="#0000EE"
posterScreenTitleColor="#EEEE00"
posterScreenSubtitleColor="#00EE00"
posterScreenSynopsisColor="#EEEEEE"
springboardScreenTitleColor="#00EE00"
springboardScreenSynopsisColor="#EEEEEE"
springboardScreenActorColor="#EEEE00"
springboardScreenDirectorColor="#EEEE00"
springboardScreenDateColor="#EEEE00">
<outline title="TED Talks" subtitle="Ideas worth spreading" img="http://ted.streamguys.net/TEDTalksvideo_tile_144.jpg" url="http://feeds.feedburner.com/tedtalks_video" />
<outline title="Loaded" subtitle="powered by CNET.com" img="http://www.cnet.com/i/pod/images/podcastsHD_loaded_300x300.jpg" url="http://loadedhdpodcast.cnettv.com" />
<outline title="Engadget" subtitle="" img="http://www.blogsmithmedia.com/www.engadget.com/media/engadgetshow_logo.png" url="http://www.engadget.com/engadgetshow_hd.xml" />
<outline title="Tech Report" subtitle="Audio Feed" img="http://techreport.com/r.x/podcast/trpodcastfeature5.png" url="http://techreport.com/podcast_mp3.rss" />
</body>
</opml>


Step 2, Edit NWM_MRSS.brs to add code to parse for mp3 files and set the correct stream format. The file should end with the following code:


else if item.enclosure.Count() > 0
' we didn't find any media:content tags, try the enclosure tag
url = ValidStr(item.enclosure@url)
if item.enclosure@type = "audio/mpeg" or LCase (Right (url, 4)) = ".mp3"
newItem.streamFormat = "mp3"
newItem.url = url
else
newStream = {
url: ValidStr(item.enclosure@url)
}

newItem.streams.Push(newStream)
endif

'PrintAA(newItem)
result.Push(newItem)
end if
next
end if

return result
end function


Step 3, Change SpringboardScreen.brs to add code to display an audio springboard screen if the content is an mp3 stream. Add an 'if' statement after the function declaration:


function ShowSpringboardScreen(episodes, selectedEpisode, leftBread, rightBread)
if episodes [selectedEpisode].streamFormat = "mp3"
return ShowAudioScreen(episodes, selectedEpisode, leftBread, rightBread)
endif


Step 4, Change the code in EpisodeScreen.brs to display the audio screen for audio content:


else if msg.isRemoteKeyPressed()
if msg.GetIndex() = 13
if content[selectedEpisode].streamFormat = "mp3"
ShowAudioScreen(content, selectedEpisode, leftBread, "")
else
ShowVideoScreen(content[selectedEpisode])
endif
end if


Step 5, Create a new file, ShowAudioScreen.brs for the springboard screen and audio player code to handle mp3 files:


function ShowAudioScreen(episodes, selectedEpisode, leftBread, rightBread)

' Use a common message port for the audio player and springboard screen
port = CreateObject("roMessagePort")

' Set up the audio player
audio = CreateObject("roAudioPlayer")
audio.SetMessagePort(port)
audio.AddContent({Url: episodes[selectedEpisode].url, StreamFormat: episodes[selectedEpisode].streamFormat})
audio.SetLoop(0)
audio.SetNext(0)

' Set up the springboard screen
screen = CreateObject("roSpringboardScreen")
screen.SetMessagePort(port)
screen.SetBreadcrumbText(leftBread, rightBread)
screen.SetStaticRatingEnabled(false)
screen.AddButton(1, "Play")
screen.SetContent(episodes[selectedEpisode])
screen.Show()

while true
msg = wait(0, port)
if type (msg) = "roSpringboardScreenEvent"
if msg.isScreenClosed()
exit while
else if msg.isButtonPressed()
button = msg.GetIndex ()
if button = 1 ' Play Button
audio.Play()
screen.ClearButtons()
screen.AddButton(2, "Pause")
screen.AddButton(4, "Stop")
else if button = 2 ' Pause Button
audio.Pause()
screen.ClearButtons()
screen.AddButton(3, "Resume")
screen.AddButton(4, "Stop")
else if button = 3 ' Resume Button
audio.Resume()
screen.ClearButtons()
screen.AddButton(2, "Pause")
screen.AddButton(4, "Stop")
else if button = 4 ' Stop Button
audio.Stop()
screen.ClearButtons()
screen.AddButton(1, "Play")
endif
else if msg.isRemoteKeyPressed()
if msg.GetIndex() = 4 ' < LEFT
screen.ClearButtons()
audio.Stop()
audio.ClearContent()
if selectedEpisode = 0
selectedEpisode = episodes.Count() - 1
else
selectedEpisode = selectedEpisode - 1
end if
audio.AddContent({Url: episodes[selectedEpisode].url, StreamFormat: episodes[selectedEpisode].streamFormat})
screen.SetContent(episodes[selectedEpisode])
screen.AddButton(1, "Play")
else if msg.GetIndex() = 5 ' > RIGHT
screen.ClearButtons()
audio.Stop()
audio.ClearContent()
if selectedEpisode = episodes.Count() - 1
selectedEpisode = 0
else
selectedEpisode = selectedEpisode + 1
end if
audio.AddContent({Url: episodes[selectedEpisode].url, StreamFormat: episodes[selectedEpisode].streamFormat})
screen.SetContent(episodes[selectedEpisode])
screen.AddButton(1, "Play")
end if
end if
else if type (msg) = "roAudioPlayerEvent"
' Do nothing
end if
end while

return selectedEpisode

end function
0 Kudos