Custom Navigation Trees: Different Structures per Share

General discussion about the media server. Feature requests. Hints, tips and tricks.
Locked
ldh2002
Posts:5
Joined:Tue Aug 25, 2009 3:39 pm
AV Hardware:TEAC WAP 5000
Custom Navigation Trees: Different Structures per Share

Post by ldh2002 » Tue Aug 25, 2009 4:51 pm

There is one detail in my tree structure I want to share.

Goal: Apply different tree structures to subsets of the music collection shared with TwonkyMedia Server 5.0.x.

Reason: I usually browse my music tree by AlbumArtist/Year/Album. For Best-of compilations, however, I never remember (and hardly care) when they were issued. Thirdly, for soundtracks the Artist is irrelevant, I only care for the Album(-title); furthermore I do not want the list cluttered with all the regular albums (not all soundtracks are compilations, btw.).
Thus I need a disjoint tree structure. As there is no filter mechanism (yet?), I found another way which allowed me to reach this goal.

Means: <include>-node

Approach:
  • Put the music data for each subset into a different folder shared in Twonky.
  • Create separate .view.xml files for each subset.
  • In the <view>-node assign each file the same path
  • In the <include>-node replace the * <tree path='*' /> with the number of the different shares, starting with 15
Helpful but not required:
  • In the <view>-node use a subview other than the ones in default.view.xml. This way there is no irritating overlap with default.view. Copy the stuff you need from default.view and assign it to your subview(s)
  • In case you want to have albums in more than one subset (e.g. best-of compilations in your usual artists collections), use symbolic links or junctions on hour hard drive structure.
Example Code:

First file ist mostly copied from default.view.xml

Code: Select all

<view name='artists' path='mypersonal.view' subviews="advanced,ipod,simple,folder">
	<include>
		<tree path='15' />
	</include>
	<navtree sortcriteria='+upnp:originalTrackNumber'>
		<container name='music' id='music' multiview='1' sortcriteria='+dc:title' upnp:originalTrackNumber='1' createClass='object.item.audioItem.musicTrack'>
			<container name='alltracks' visibility="advanced,ipod,simple" id='music/all' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container'/>	
			<container name='artistindex' visibility="advanced" id='music/artistindex' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
				<container buildon='upnp:artist[3]' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
					<container buildon='upnp:artist' sortcriteria='+dc:title' class='object.container.person.musicArtist' createClass='object.item.audioItem.musicTrack'>
						<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' />
						<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
					</container>
				</container>
			</container>
			<container name='artistalbum' visibility="simple" id='music/artistalbum' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>				
				<container name='allname'  buildon='upnp:album' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
				<container buildon='upnp:albumArtist[5]' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
					<container buildon='upnp:albumArtist[1]' sortcriteria='+dc:title' class='object.container.person.albumartist' createClass='object.item.audioItem.musicTrack'>
						<container buildon='upnp:albumArtist' sortcriteria='+upnp:originalTrackNumber' class='object.container.person.albumartist' createClass='object.item.audioItem.musicTrack'>
							<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' class='object.container.album.musicAlbum' createClass='object.item.audioItem.musicTrack'/>
						</container>
					</container>
				</container>
			</container>
			<container name='Interpret/Jahr/Album' visibility="simple" id='music/albumartists' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>				
				<container name='allname'  buildon='upnp:album' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
				<container buildon='upnp:albumArtist[5]' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
					<container buildon='upnp:albumArtist[1]' sortcriteria='+dc:title' class='object.container.person.albumartist' createClass='object.item.audioItem.musicTrack'>
						<container buildon='upnp:albumArtist' sortcriteria='+dc:title' class='object.container.person.albumartist' createClass='object.item.audioItem.musicTrack'>
							<container name='albums'buildon='upnp:album' sortcriteria='+upnp:originalTrackNumber' upnp:originalTrackNumber='1' class='object.container.person.albumartist' createClass='object.item.audioItem.musicTrack'>								
								<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' class='object.container.album.musicAlbum' createClass='object.item.audioItem.musicTrack'/>
							</container>
							<container buildon='dc:date[1:4]' albumart='1' sortcriteria='+dc:date' upnp:originalTrackNumber='2' class='object.container' createClass='object.item.audioItem.musicTrack'>
								<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' class='object.container.album.musicAlbum' createClass='object.item.audioItem.musicTrack'/>							
							</container>								
						</container>
					</container>
				</container>
			</container>
			<container name='genre' visibility="advanced,ipod" id='music/genre' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
				<container buildon='upnp:genre' sortcriteria='+dc:title' class='object.container.genre.musicGenre' createClass='object.item.audioItem.musicTrack' />
			</container>
			<container name='genrealbum' visibility="advanced" sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
				<container buildon='upnp:genre' sortcriteria='+dc:title' class='object.container.genre.musicGenre' createClass='object.item.audioItem.musicTrack' >
					<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
				</container>
			</container>
			<container name='genreartist' visibility="advanced" id='music/genreartistalbum' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
				<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' >
					<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' >
						<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' />
						<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
					</container>
					<container buildon='upnp:artist' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
						<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' />
						<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
					</container>
				</container>
				<container buildon='upnp:genre' sortcriteria='+dc:title' class='object.container.genre.musicGenre' createClass='object.item.audioItem.musicTrack'>
					<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' >
						<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' />
						<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
					</container>
					<container buildon='upnp:artist' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
						<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' />
						<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
					</container>
				</container>
			</container>
			<container name='rating' visibility="advanced" id='music/rating' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
				<container buildon='pv:rating' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack' />
			</container>
			<container name='artist' visibility="ipod,advanced" id='music/artists' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
				<container name='allname' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' />
				<container buildon='upnp:artist' sortcriteria='+dc:title' class='object.container.person.musicArtist' createClass='object.item.audioItem.musicTrack' />
			</container>
			<container name='album' visibility="ipod,advanced" id='music/albums' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' >
				<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
			</container>
			<container name='composer' visibility="ipod,advanced" id='music/composers' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container' >
				<container buildon='upnp:author' sortcriteria='+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
			</container>
			<container name='folder' visibility="simple,advanced,folder" id='music/folders' class='object.container.storageFolder' createClass='object.item.audioItem.musicTrack'>
				<container buildon='res' sortcriteria='+upnp:originalTrackNumber,+dc:title' createClass='object.item.audioItem.musicTrack' class='object.container.storageFolder' />
			</container>
			<container name='playlists' visibility="advanced,ipod,simple" id='music/playlists' class='object.container' createClass='object.item.audioItem.musicTrack,object.item.audioItem.online.musicTrack' sortcriteria='+upnp:originalTrackNumber,+dc:title'   restricted='0' flags='pv:playlistRoot=Music' >
				<container name='playlistrecentlyadded' filteron='pv:addedLast60' sortcriteria='-pv:addedTime' createClass='object.item.audioItem.musicTrack' maxitems='500' upnp:originalTrackNumber='3' restricted='1' class='object.container.playlistContainer' flags='pv:smartplaylist=1' />
				<container name='playlistmostplayed' filteron='pv:playcount' sortcriteria='-pv:playcount' createClass='object.item.audioItem.musicTrack' maxitems='500' upnp:originalTrackNumber='1'  restricted='1' class='object.container.playlistContainer' flags='pv:smartplaylist=1' />
				<container name='playlistlastplayed' filteron='pv:lastPlayedTime' sortcriteria='-pv:lastPlayedTime' createClass='object.item.audioItem.musicTrack' maxitems='500' upnp:originalTrackNumber='2' restricted='1' class='object.container.playlistContainer' flags='pv:smartplaylist=1' />
				<container name='playlisthighlyrated' filteron='pv:highrated' sortcriteria='-pv:rating' createClass='object.item.audioItem.musicTrack' maxitems='500' upnp:originalTrackNumber='4' class='object.container.playlistContainer' restricted='1'  flags='pv:smartplaylist=1' />
				<container buildon='upnp:playlist' sortcriteria='+upnp:originalTrackNumber' upnp:originalTrackNumber='5' createClass='object.item.audioItem.musicTrack,object.item.audioItem.online.musicTrack' class='object.container.playlistContainer' />
			</container>
		</container>
	</navtree>
</view>
Second file is used to view my best-of compilations (without displaying the year)

Code: Select all

<view name='best' path='mypersonal.view' subviews="advanced,ipod,simple,folder">
	<include>
		<tree path='16' />
	</include>
	<navtree sortcriteria='+upnp:originalTrackNumber'>
		<container name='music' id='music' multiview='1' sortcriteria='+dc:title' upnp:originalTrackNumber='1' createClass='object.item.audioItem.musicTrack'>
			<container name='Best Compilations' visibility="advanced, simple" id='music/bestcompilations' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>				
				<container name='allname'  buildon='upnp:album' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
				<container buildon='upnp:albumArtist[5]' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
					<container buildon='upnp:albumArtist' sortcriteria='+dc:date' class='object.container.person.albumartist' createClass='object.item.audioItem.musicTrack'>
							<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' class='object.container' createClass='object.item.audioItem.musicTrack' />
					</container>
				</container>
			</container>
		</container>
	</navtree>
</view>
Third file is displaying my soundtracks (sorted by album title).

Code: Select all

<view name='soundtracks' path='mypersonal.view' subviews="advanced,ipod,simple,folder">
	<include>
		<tree path='17' />
	</include>
	<navtree sortcriteria='+upnp:originalTrackNumber'>
		<container name='music' id='music' multiview='1' sortcriteria='+dc:title' upnp:originalTrackNumber='1' createClass='object.item.audioItem.musicTrack'>
			<container name='Soundtracks' visibility="advanced, simple" id='music/soundtracks' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>				
				<container name='allname'  buildon='upnp:album' sortcriteria='+upnp:originalTrackNumber' createClass='object.item.audioItem.musicTrack' class='object.container.album.musicAlbum' />
				<container buildon='upnp:album[5]' sortcriteria='+dc:title' class='object.container' createClass='object.item.audioItem.musicTrack'>
					<container buildon='upnp:album' albumart='1' sortcriteria='+upnp:originalTrackNumber' class='object.container' createClass='object.item.audioItem.musicTrack'/>
				</container>
			</container>
		</container>
	</navtree>
</view>
Last edited by ldh2002 on Wed Aug 26, 2009 9:34 am, edited 2 times in total.

PeeBee
Posts:392
Joined:Sat Jun 13, 2009 12:16 pm
AV Hardware:Buffalo LS Pro; PS3; Samsung LE37B650

Re: Custom Navigation Trees: Different Structures per Share

Post by PeeBee » Tue Aug 25, 2009 6:13 pm

The 5.1 Betas allow you to have a different view per client.

PB
Samsung LE37B650T2WXXU; Liteon 5055GDL+ HDD/DVD Recorder; Playstation 3; Iomega Screenplay HD 500GB; Buffalo Linkstation Pro LS-320GL (running Twonky 6.0.30, SqueezeBox Server 7.6 and acting as a Print Server)

ldh2002
Posts:5
Joined:Tue Aug 25, 2009 3:39 pm
AV Hardware:TEAC WAP 5000

Re: Custom Navigation Trees: Different Structures per Share

Post by ldh2002 » Wed Aug 26, 2009 9:40 am

PeeBee wrote:The 5.1 Betas allow you to have a different view per client.
The 5.0.x version also allows for this. My intention, however, was to have different views on one client, active simultaneously.

Cheers ldh

hvaleton
Posts:2
Joined:Fri Sep 18, 2009 3:06 pm
AV Hardware:Linn ADS , Synology DS408, TMS 5.1

Re: Custom Navigation Trees: Different Structures per Share

Post by hvaleton » Fri Sep 18, 2009 3:26 pm

Hi ldh2002,

I have exactly the same problem you seem to have found the answer for.
My collection consists of two distinct sub collections: classical and pop music
I have tried to distinguish between those two by using 'filteron'. But this can only filter on the fact that a certain tag is filled or not. It cannot filter on actual content.
So I determine pop music by filtering on the fact that the 'album artist' tag is filled.
This of course implies having to get rid of all 'album artist' tags in my classical flacs.
Next I determine classical music by filtering on the the fact that the 'Composer' tag is filled.
This is rather more easily done by deleting all composer tags in my pop collection, which I'm not interested in anyway.
But still, it's not a very charming solution (not to mention time consuming) and in some cases it doesn't even work because of some tags that remain mysteriously impervious to deleting....
So if your solution still works in the new 5.1 version of TMS I woud be very happy.
Have you tried it out yet?

I remember Twonky stating somewhere in the custom tree manual that the < tree path > functionality would only be activated in a later release....

Another thing that puzzles me is your usage of a number to indicate a share. Is there a specific reason for this? Why not simply use the name of the share, in my case M:\music\01_KLASSIEK and M:\music\02_POP ?
And why start with 15?

I'd be very grateful for your thoughts on the above.

Thanks in advance,

Hans

ldh2002
Posts:5
Joined:Tue Aug 25, 2009 3:39 pm
AV Hardware:TEAC WAP 5000

Re: Custom Navigation Trees: Different Structures per Share

Post by ldh2002 » Thu Oct 22, 2009 9:45 pm

Hello Hans,

eventually I upgraded to v5.1 to see how it behaves.

Most important point first:
I am going to downgrade again pretty soon.

The <include>-tag doesn't seem to exist or work anymore in v5.1

When I experimented with the <include>-tag in v5.0.68 I noticed that the value I have to use as <tree path > is not the actual path in the OS, but the path that Twonky assigns to the Share in its own tree structure.

Closing, I personally hope that a future subversion of Twonky will continue using <include>
For the whole community I hope for an updated TMS-View-Configuration documentation which is currently quite outdated.

Gruß

Lars

Locked