Folder structure / Samsung TV

Anonymous
2012-09-24
2014-12-30

  • Anonymous
    2012-09-24

    Some people have their media files finely organized into folders and only want to browse those files the shortest / fastest way possible.

    Now some Samsung TVs don't let you simply browse a DLNA server, but instead offer you the categories (Pictures, Music, Videos) which each drop into the respective category offered by MiniDLNA. No direct browsing access there. :(

    Since those "organized" people (such as me) don't need any of the category entries other than what's in the "Folders" item, that's an unnecessary extra step to reach the media.

    The solution: this patch turns the video category into simple folder browsing mode:

    diff -ruN minidlna-1.0.25.orig/scanner.c minidlna-1.0.25/scanner.c
    --- minidlna-1.0.25.orig/scanner.c      2012-06-29 23:11:29.000000000 +0200
    +++ minidlna-1.0.25/scanner.c   2012-09-23 23:27:30.000000000 +0200
    @@ -479,7 +479,7 @@
            else if( is_video(name) )
            {
                    orig_name = strdup(name);
    -               strcpy(base, VIDEO_DIR_ID);
    +               strcpy(base, VIDEO_ID);
                    strcpy(class, "item.videoItem");
                    detailID = GetVideoMetadata(path, name);
                    if( !detailID )
    @@ -549,8 +549,6 @@
                               MUSIC_PLIST_ID, MUSIC_ID, _("Playlists"),
                                     VIDEO_ID, "0", _("Video"),
    -                            VIDEO_ALL_ID, VIDEO_ID, _("All Video"),
    -                            VIDEO_DIR_ID, VIDEO_ID, _("Folders"),
                                     IMAGE_ID, "0", _("Pictures"),
                                 IMAGE_ALL_ID, IMAGE_ID, _("All Pictures"),
    

    Pictures and Music could probably be converted easily as well.

    Another thing that irritated me was this:
    When you have several media_dirs (of the same type, videos in my case) and browse that category, contents of all the media_dirs are mixed up.

    I created another patch so it creates a folder for each media_dir and adds the contents to that instead, so it doesn't mix up anymore.
    Here you go:

    diff -ruN minidlna-1.0.25.orig/scanner.c minidlna-1.0.25/scanner.c
    --- minidlna-1.0.25.orig/scanner.c      2012-06-29 23:11:29.000000000 +0200
    +++ minidlna-1.0.25/scanner.c   2012-09-24 01:26:11.000000000 +0200
    @@ -729,6 +729,32 @@
                    return;
            DPRINTF(parent?E_INFO:E_WARN, L_SCANNER, _("Scanning %s\n"), dir);
    +
    +       if( !parent )
    +       {
    +               // This is a media_dir entry - it has no parent.
    +
    +               // Insert dir as a directory entry to the browse dir
    +               // instead of directly adding it's contents to the browse dir.
    +               startID = get_next_available_id("OBJECTS", BROWSEDIR_ID);
    +               name = escape_tag(dir, 1);
    +               insert_directory(basename(name), dir, BROWSEDIR_ID, "", startID);
    +
    +               // Now scan the dir with it's directory entry as the parent.
    +               // That way, the content will be added to the directory entry,
    +               // not the browse dir. Hence, the different media_dirs show up
    +               // as folders and the contents don't mix up.
    +               sprintf(parent_id, "$%X", startID);
    +               ScanDirectory(dir, parent_id, dir_type);
    +
    +               free(name);
    +
    +               // We can return early here since the contents of this dir
    +               // have been added now.
    +               DPRINTF(E_WARN, L_SCANNER, _("Scanning %s finished (%llu files)!\n"), dir, fileno);
    +               return;
    +       }
    +
            switch( dir_type )
            {
                    case ALL_MEDIA:
    @@ -752,11 +778,6 @@
                    return;
            }
    -       if( !parent )
    -       {
    -               startID = get_next_available_id("OBJECTS", BROWSEDIR_ID);
    -       }
    -
            for (i=0; i < n; i++)
            {
     #if !USE_FORK
    @@ -793,14 +814,7 @@
                    free(namelist[i]);
            }
            free(namelist);
    -       if( parent )
    -       {
    -               chdir(dirname((char*)dir));
    -       }
    -       else
    -       {
    -               DPRINTF(E_WARN, L_SCANNER, _("Scanning %s finished (%llu files)!\n"), dir, fileno);
    -       }
    +       chdir(dirname((char*)dir));
     }
     void
    

    Please be kind with me, I'm not so good with C so there is probably "room for improvements". :)

    Note: a rescan / rebuild of your db is required.

     

  • Anonymous
    2012-09-24

    I created a fork on github.

    I believe this is off the latest cvs. It also needed another patch to compile on older libavutil versions that don't have error.h / av_strerror().

     
  • R S
    R S
    2012-09-24

    Awesome.. I really needed the Second patch….
    So.. quick question.. How does one apply that?
    Step 1: I create a file name folderPatch
    Step 2. Insert the conttenet of the file to be what you have above
    Step 3: apply the patch? How
    Step 4: Make clean
    Step 5: Make
    Step 6: sudo make install

    can you explain how to do Step 3?

     
  • Cecil Coupe
    Cecil Coupe
    2012-09-25

    3)  use the command 'patch' to appy the patch file to the minidlna/ source directory.
    3a) read the patch manual. 'man patch'
    3b) think about what could go wrong
    3c) make backups of the source before patching
    3d) decide if you need the -p0 or -p1

     
  • peteS
    peteS
    2013-01-21

    Thank you. Nicely done.

    Actually thanks to your second patch the audio folder traversal is fine. Going to music->folders isn't that big of a deal. In a few spare minutes I tried modifying the code for audio to mirror what you did for video, but kept losing playlist functionality along the way. I guess this warrants a closer look with undivided attention, but like I said it's good enough as is.

    I don't know if UPNP supports this, but what would really be cool is being able to create playlists on the fly from the DLNA client by just browsing audio files and flagging/tagging them somehow. I'm sure most people would agree that server side static playlist creation is a real PITA. I'll take a look to see what control codes can be sent to the server. No promises though. :-)

     

  • Anonymous
    2013-03-01

    I installed minidnla in ubuntu 12.10 using a ppa.

    Can somebody explain me how to easily use this patch?

    Thanks!

     

  • Anonymous
    2013-03-25

    You need to download source and build and install from there.  If you've never done that before, you might find this link useful: https://help.ubuntu.com/community/CompilingEasyHowTo

    Once you understand that, you can download the source from the sourceforge project page.

    Good luck!

     
  • Logan007
    Logan007
    2013-05-17

    rhartman, I happened to come across your first patch… it seems we did exactly the same, independently - I also own Samsung TVs.  :)

    I found that scanner.h needs a change, too:

    #define VIDEO_ALL_ID            "2$80" // !!! was: 2$8

    Otherwise, the 7th, 8th, or 9th directory at root (one of them of which I don't remember the correct number) will not show the content you expect.

     
  • Dennis  Lopeman
    Dennis Lopeman
    2014-12-10

    I'm sorry to resurrect this OLD post... but it is still valid (or at least it's what I'm looking for!!) The code has slightly changed since this release but there was enough here that I could ALMOST do it. I'm not a C programmer, so maybe that's my problem!! :)

    Summary: I did this for VIDEO, but also wanted the same for MUSIC and PICTURES. I, too, am very organized how I store my stuff and simply want to browse right to the content (FOLDERS) in each category. I made the changes (which I'll post below) and only VIDEOS and PICTURES are working... MUSIC, however, seems to NOT show me folders, but is trying to do somethings else (by Genre, perhaps; I don't let it finish as I have 10000+ files!!!)

    (note that I use //dennis to comment - makes it easier to find!)

    scanner.c

        if( (types & TYPE_IMAGES) && is_image(name) )
        {
                if( is_album_art(name) )
                        return -1;
                //dennis - strcpy(base, IMAGE_DIR_ID);
                strcpy(base, IMAGE_ID);
                strcpy(class, "item.imageItem.photo");
                detailID = GetImageMetadata(path, name);
        }
        else if( (types & TYPE_VIDEO) && is_video(name) )
        {
                orig_name = strdup(name);
                //dennis - strcpy(base, VIDEO_DIR_ID);
                strcpy(base, VIDEO_ID);
                strcpy(class, "item.videoItem");
                detailID = GetVideoMetadata(path, name);
                if( !detailID )
                        strcpy(name, orig_name);
        }
        else if( is_playlist(name) )
        {
                if( insert_playlist(path, name) == 0 )
                        return 1;
        }
        if( !detailID && (types & TYPE_AUDIO) && is_audio(name) )
        {
                //dennis - strcpy(base, MUSIC_DIR_ID);
                strcpy(base, MUSIC_ID);
                strcpy(class, "item.audioItem.musicTrack");
                detailID = GetAudioMetadata(path, name);
        }
    

    ...

        const char *containers[] = { "0","-1",   "root",
                                MUSIC_ID, "0", _("Music"),
                            //dennis - MUSIC_ALL_ID, MUSIC_ID, _("All Music"),
                          //dennis - MUSIC_GENRE_ID, MUSIC_ID, _("Genre"),
                         //dennis - MUSIC_ARTIST_ID, MUSIC_ID, _("Artist"),
                          //dennis - MUSIC_ALBUM_ID, MUSIC_ID, _("Album"),
                            //dennis - MUSIC_DIR_ID, MUSIC_ID, _("Folders"),
                          //dennis - MUSIC_PLIST_ID, MUSIC_ID, _("Playlists"),
    
                                VIDEO_ID, "0", _("Video"),
                            //dennis - VIDEO_ALL_ID, VIDEO_ID, _("All Video"),
                            //dennis - VIDEO_DIR_ID, VIDEO_ID, _("Folders"),
    
                                IMAGE_ID, "0", _("Pictures"),
                            //dennis - IMAGE_ALL_ID, IMAGE_ID, _("All Pictures"),
                           //dennis - IMAGE_DATE_ID, IMAGE_ID, _("Date Taken"),
                         //dennis - IMAGE_CAMERA_ID, IMAGE_ID, _("Camera"),
                            //dennis - IMAGE_DIR_ID, IMAGE_ID, _("Folders"),
    
                            BROWSEDIR_ID, "0", _("Browse Folders"),
                        0 };
    

    scanner.h

    #define MUSIC_ID                "1"
    #define MUSIC_ALL_ID            "1$4"
    #define MUSIC_GENRE_ID          "1$5"
    #define MUSIC_ARTIST_ID         "1$6"
    #define MUSIC_ALBUM_ID          "1$7"
    #define MUSIC_PLIST_ID          "1$F"
    #define MUSIC_DIR_ID            "1$14"
    #define MUSIC_CONTRIB_ARTIST_ID "1$100"
    #define MUSIC_ALBUM_ARTIST_ID   "1$107"
    #define MUSIC_COMPOSER_ID       "1$108"
    #define MUSIC_RATING_ID         "1$101"
    #define VIDEO_ID                "2"
    #define VIDEO_ALL_ID            "2$80"
    #define VIDEO_GENRE_ID          "2$9"
    #define VIDEO_ACTOR_ID          "2$A"
    #define VIDEO_SERIES_ID         "2$E"
    #define VIDEO_PLIST_ID          "2$10"
    #define VIDEO_DIR_ID            "2$15"
    #define VIDEO_RATING_ID         "2$200"
    #define IMAGE_ID                "3"
    #define IMAGE_ALL_ID            "3$B"
    #define IMAGE_DATE_ID           "3$C"
    #define IMAGE_ALBUM_ID          "3$D"
    #define IMAGE_CAMERA_ID         "3$D2" // PlaysForSure == Keyword
    #define IMAGE_PLIST_ID          "3$11"
    #define IMAGE_DIR_ID            "3$16"
    #define IMAGE_RATING_ID         "3$300"
    

    Notice in scanners.h I changed, per previous post, #define VIDEO_ALL_ID "2$80"

    Do I have to also change the equivalent for MUSIC and IMAGE?
    #define MUSIC_ALL_ID "1$4"
    #define IMAGE_ALL_ID "3$B"

    It would be nice to better understand what these values are! Any guides on that? How did that person know it needed to be changed to 2$80

    I also don't prefer the "Recent 50 x" folder and commented out all the pertinent lines in

    containers.c

            /* Recent 50 audio items */
            //{ "Recently Added",
              //"1$FF0",
              //NULL,
              //"\"1$FF0$\" || OBJECT_ID",
              //"\"1$FF0\"",
              //"o.OBJECT_ID",
              //"(select null from DETAILS where MIME glob 'a*' and timestamp > (strftime('%s','now') - "NINETY_DAYS") limit 50)",
              //"MIME glob 'a*' and REF_ID is NULL and timestamp > (strftime('%s','now') - "NINETY_DAYS")",
              //"order by TIMESTAMP DESC",
              //50,
              //0,
            //},
    

    etc etc etc for all 3 stanzas

    I added this just in case it's affecting it somehow.

    Is there a better way?? Maybe an addition to minidlna.conf could be cool, like:
    MagicFolders=no

    I messed with the root_container setting, but it seems to be just for music... It might be cool to have something similar for the media lines... like:

    media_dir=BV,/DataVolume/shares/videos/
    media_dir=BA,/DataVolume/shares/audio/
    media_dir=BP,/DataVolume/shares/pictures/
    

    Where the B (or whatever letter) denotes that you only want to Browse the content of that type. (maybe I should add this to the enhancement requests!)

    Thanks, in advance! GREAT Product!! Has worked for me for YEARS! (I just upgraded a couple days ago, thus the desire to tweak it!)

    -dennis

     
  • Dennis  Lopeman
    Dennis Lopeman
    2014-12-12

    Ok... so... I figured out how to use the "patch" command!! Yay me. I did find another patch someone posted in the Tickets:Feature Requests section (he/she called it diff.diff) and I just ran that on a clean source of minidlna 1.1.4 and it compiled and now I'm building my DB!!! Woooo hooo... fingers crossed. Here's the link to that file in which they wanted what seems to be the same as we do here:

    https://sourceforge.net/p/minidlna/feature-requests/101/

    Although I'm thinking I'm going to have to REcompile to get of the "Last 50 Recent blah blah blah" folders again... we'll see!

     
    Last edit: Dennis Lopeman 2014-12-12
  • Dennis  Lopeman
    Dennis Lopeman
    2014-12-12

    OK - UPDATE (I want to keep this as current as possible as I see that this is a VERY ACTIVE forum!! LOL joking - where is everyone?!?! Should I be posting in the NetGear forum now?)

    I just looked and I see ALL the Special directories even after patching with that diff.diff patch from above. There might be a speically setting I need in minidlna.conf or something... so this might not be what we're after... I'll keep hunting.

     
  • Dennis  Lopeman
    Dennis Lopeman
    2014-12-12

    SWEEEEEEET. I found it! I poked around the code and saw a new OPTION - I added this to /etc/minidlna.conf:

    # set this to show/disable all special directories, like "All Music, etc..."
    disable_extended_directories=yes
    

    I still see the "Recently Added" folders, so I'll hack the source putting comments in like I showed up above. I'll see if I can find a more elegant/official way to disable magic_containers.... like maybe "magic_containers=no" or "virtual_folders=no" (or both, differentiating between Special folders and Recently Added) in minidlna.conf would be cool!!! (hint hint wink wink)

    Well I hope this all helps someone(s) Enjoy! I "shouldn't" need to return, except maybe in a few years when I go through all this again on newer versions!

     
    Last edit: Dennis Lopeman 2014-12-12
  • Dennis  Lopeman
    Dennis Lopeman
    2014-12-30

    FYI - I got this to work great, including the COMMENTING out the stanzas in containers.c so I don't see "Recently Added" folders, either.