none
Buscar archivos mp3 da error a referencia a objeto no establecida como instancia de un objeto RRS feed

  • Pregunta

  • Bueno les comento un poco el codigo : Sirve para buscar canciones dentro de mi pc y uso una libreria llamada TagLib que anda muy bien y me obtiene los tag de archivos .mp3 como titulo, duracion, etc.

    Todo funciona bien pero no me encuentra lo que le paso por parametro con los titulos que  obtengo ya que estimo que debe ser porque los titulos tienen caracteres en mayuscula entonces intento pasar a minusculas los titulos con .ToLower() y me tira error de compilacion  "Información adicional: Referencia a objeto no establecida como instancia de un objeto." ,  no entiendo porque, ya que uso la mismas variables , deberia lanzarme el mismo error sin usar el metodo que quiero usar.  Aunque cree una variable nueva string y le aplique el .Tolower , sigue dandome el mismo error, no se como solucionarlo .No solo da error con ese metodo sino con todos los metodos aplicables al string, ya sea directamente desde el objeto del TagLib como a un nuevo objeto string .Espero puedan ayudarme o puedan aconsejarme de alguna manera mas facil de encontrar canciones en mi pc o de cualquier tipo de archivo para futuros proyectos,espero haberme explicado bien , desde ya gracias. Aca abajo les adjunto parte del codigo :

    string tag_nom_cancion;
            public string obtener_nom_tag_can
            {
    
                get
                {
                    return tag_nom_cancion;
                }
                set
                {
                    tag_nom_cancion = value;
                }
    
            }

     

    public void Buscar_cancion(string nom_video) { List<string> nombre_carpetas = new List<string>(); List<string> nombre_de_archivos = new List<string>(); string biblioteca1 = "url_ubicacion1_de_carpetas_con_musica_adentro"; string[] nombre_de_carpetas = Directory.GetDirectories(biblioteca1); foreach (var n_ar in nombre_de_carpetas) { DirectoryInfo directorios = new DirectoryInfo(n_ar); nombre_carpetas.Add(directorios.Name); } foreach (string nom_carpeta in nombre_carpetas) { string[] archivos_en_carpe = Directory.GetFiles(biblioteca1 + "/" + nom_carpeta); foreach (var archivo in archivos_en_carpe) { FileInfo archivos = new FileInfo(archivo); if (archivos.Name.Contains(".mp3")) { TagLib.File cancion = TagLib.File.Create(biblioteca1+"/"+nom_carpeta+"/"+archivos.Name);//funciona- //aca me da error--> obtener_nom_tag_can = cancion.Tag.Title.ToLower();//aca obtengo los titulos de las canciones que tengo.

    nombre_de_archivos.Add(obtener_nom_tag_can);//aunque me da error, me guarda todos los nombres en la lista

    //tambien probe asi :

    string nombre_cancion_tag = obtener_nom_tag_can.ToLower(); // da error

    nombre_de_archivos.Add(nombre_cancion_tag);

    //tambien probe asi :

    string nom_cancion = cancion.Tag.Title.ToLower(); //da error

    nombre_de_archivos.Add(nom_cancion) } } }





    domingo, 25 de enero de 2015 4:35

Respuestas

  • hola

    no entiendo poque un codigo tan complejo si podrias hacerlo en pocas lineas usando

    GetFiles(String, String, SearchOption)

    string[] mp3List = Directory.GetFiles(biblioteca1, "*.mp3", SearchOption.AllDirectories);


    asi de simple obtienes todos los mp3 de carpeta y subcarpeta, sin tener que definir ni un solo foreach

    despues si necesitas usad

    foreach(string mp3 in mp3List){
    
       TagLib.File cancion = TagLib.File.Create(mp3);
    
      //resto codigo
    
    }


    recuerda que los archivos mp3 puede que no tengan metadata, por eso usar el Tag.Title directo no es aconsejable, puedes obtener un null en la propiedad Tag o en el Title, solo pon un breakpoint y pasa el mouse encima de estas propiedades para ver la informacion

    sino usa

    if(cancion.Tag != null && cancion.Tag.Title != null){
    
       //aqui si accedes de forma segura
    
    }


    ----

    analiza este articulo

    Cómo: Copiar directorios

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    domingo, 25 de enero de 2015 13:58

Todas las respuestas

  • Casi seguro que el error te sale porque Title es null (y en consecuencia Title.ToLower() da un error de referencia no establecida). Presumiblemente, la librería que estás usando devuelve null en el Title cuando el mp3 que está leyendo no tiene grabado ningún Title. El único remedio es que en tu programa primero compruebes si vale null antes de intentar pasarlo a minúsculas.

    Una de las formas más compactas de resolverlo es esta:

    obtener_nom_tag_can = (cancion.Tag.Title ?? "").ToLower();

    domingo, 25 de enero de 2015 9:31
    Moderador
  • hola

    no entiendo poque un codigo tan complejo si podrias hacerlo en pocas lineas usando

    GetFiles(String, String, SearchOption)

    string[] mp3List = Directory.GetFiles(biblioteca1, "*.mp3", SearchOption.AllDirectories);


    asi de simple obtienes todos los mp3 de carpeta y subcarpeta, sin tener que definir ni un solo foreach

    despues si necesitas usad

    foreach(string mp3 in mp3List){
    
       TagLib.File cancion = TagLib.File.Create(mp3);
    
      //resto codigo
    
    }


    recuerda que los archivos mp3 puede que no tengan metadata, por eso usar el Tag.Title directo no es aconsejable, puedes obtener un null en la propiedad Tag o en el Title, solo pon un breakpoint y pasa el mouse encima de estas propiedades para ver la informacion

    sino usa

    if(cancion.Tag != null && cancion.Tag.Title != null){
    
       //aqui si accedes de forma segura
    
    }


    ----

    analiza este articulo

    Cómo: Copiar directorios

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    domingo, 25 de enero de 2015 13:58
  • Muchas gracias por sus respuestas me sirvieron mucho, ahora compruebo si es null el .Title y y luego aplico el metodo .ToLower, funciona. 

    En mi opinion personal es muy precario este metodo de busqueda ya que cuando agrego a la lista los titulos de las canciones solo tengo el metodo .Contains() para comparar de alguna manera lo que paso por parametro con el titulo que obtengo,ya que los metodos .Equals() y CompareTo() estimo deben ser menos utiles.Me da resultados muy pobres ya que si no coincide exactamente no me devuelve nada,ahora pregunto.. tengo que hacer un char[] alojando lo que paso por parametro y otro char[] con los titulos que obtengo y luego verificar si hay coincidencias en mas de 3 o 4 caracteres como para que sea mas fexible la busqueda? por ejemplo:

    si un titulo es "06 infinito" y paso por parametro infinito no me lo encuentra utilizando .Contains(), como puedo hacer? sirve descomponer en caracteres el string? y asi mismo si descompongo tengo que usar expresiones regulares para que me encuentre coincidencias en los caracteres del string por parametro con el otro  obtenido del titulo? Espero haberme explicado,desde ya gracias

    domingo, 25 de enero de 2015 21:28
  • hola

    >>si un titulo es "06 infinito" y paso por parametro infinito no me lo encuentra utilizando .Contains(), como puedo hacer?

    me parece muy raro lo que cometas, porque si haces

            public bool TestComparar()
            {
                string cadena = "06 infinito";
    
                if (cadena.Contains("infinito"))
                {
                    return true;
                }
    
                return false;
    
            }

    esto retorna true

    o sea ese texto si contiene la palabra que mencionas, por eso es raro lo que comentas

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    domingo, 25 de enero de 2015 22:57
  • Es cierto, error mio, pido disculpas , yo utilizaba el metodo Contains() en la lista directamente en vez del elemento individual. Asi mismo, me gustaria saber de que manera puedo hacer mas flexible la busqueda porque sigue siendo muy pobre para mi gusto, por ejemplo  si tengo este nombre "smells  like teen spirit" y paso por parametro "smell like" , no me lo encuentra con .Contains(),tengo que crear un metodo que me agrege y quite la s? o hay alguna otra manera?
    lunes, 26 de enero de 2015 0:37
  • >>por ejemplo  si tengo este nombre "smells  like teen spirit" y paso por parametro "smell like" , no me lo encuentra con .Contains()

    ojo porque en el texto entre smells y like hay dos espacios entre medio, si en el contains pones solo uno es logico que no lo va a encontrar

    pero usa "smells  like" y veras como lo encuentra

    si te animas puedes usar linq

    string[] mp3List = Directory.GetFiles(biblioteca1, "*.mp3", SearchOption.AllDirectories);
    
    var result = (from mp3 in mp3List
                       let cancion = TagLib.File.Create(mp3)
                     where cancion.Tag.Title != null && cancion.Tag.Title.Contains(txtBusqueda.Text)
                     select mp3).ToList();

    asi como veras queda mucho mejor el codigo

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    lunes, 26 de enero de 2015 0:50