Проблемы с воспроизведением mp3s после редактирования изображения id3 - PullRequest
2 голосов
/ 04 июля 2011

Из-за аппаратных ограничений производимое нами программное обеспечение пытается обеспечить приемлемую скорость передачи любого аудиофайла, который он импортирует в свою библиотеку (готовый для копирования на оборудование).

Недавно мы началииспользуя FFmpeg для преобразования ряда различных типов аудио в mp3, чтобы их можно было импортировать и использовать на нашем оборудовании.Несмотря на то, что преобразование работает нормально, а затем файлы mp3 работают на нашем оборудовании, у нас возникают проблемы, особенно при добавлении обложки альбома в теги ID3 mp3.Трек не будет воспроизводить аудио в нашем программном обеспечении.Также кажется, что Windows не может получить значения тегов ID3 ​​в проводнике, но проигрыватель Windows Media все равно будет воспроизводить дорожку.

Эта проблема возникает только при изменении тегов ID3 ​​недавно преобразованных mp3-файлов после использованияFFmpeg.Смена тегов на mp3-файлах из других источников или на тех, у которых уже есть обложка альбома с тегами ID3, подойдет.

Код для использования FFmpeg из нашего программного обеспечения следующий:

        private const string SAMPLE_RATE = "44100";

        ...

        //create temp file for output
        outFile = Path.GetTempFileName();
        outFile = Path.ChangeExtension(outFile, "mp3");

        if (!File.Exists(inFile))
            return false;

        string metadata = (inFile.EndsWith("mp3")) ? " " : " -map_meta_data 0:0 ";

        //build process
        string workingDirectory = Environment.CurrentDirectory;
        ProcessStartInfo FFmpegProcessInfo = new ProcessStartInfo();
        FFmpegProcessInfo.WorkingDirectory = workingDirectory;
        FFmpegProcessInfo.FileName = "ffmpeg.exe";
        FFmpegProcessInfo.Arguments = "-i \"" + inFile + "\"" +  " -ar "+SAMPLE_RATE + metadata + "\"" + outFile + "\""; //default conversion to SAMPLE_RATE
        FFmpegProcessInfo.CreateNoWindow = true; //hide from user
        //let us grab the output
        FFmpegProcessInfo.RedirectStandardError = true;
        FFmpegProcessInfo.RedirectStandardOutput = true;
        FFmpegProcessInfo.UseShellExecute = false;
        Process p = Process.Start(FFmpegProcessInfo);

Чтобы изменитьТеги ID3, которые мы начали использовать TagLib-Sharp, и код для изменения тегов ID3:

    public void SetId3Tags(string path, Bitmap image, IDictionary<string, string> values)
    {
        FileInfo fileInfo = new FileInfo(path);
        fileInfo.Attributes = FileAttributes.Normal;

        try
        {
            TagLib.File tagFile = TagLib.File.Create(path);
            if (values.ContainsKey("Title"))
                tagFile.Tag.Title = values["Title"];
            if (values.ContainsKey("Artist"))
                tagFile.Tag.Performers = new string[1] { values["Artist"] };
            if (values.ContainsKey("Comments"))
                tagFile.Tag.Comment = values["Comments"];
            if (image != null) {
                string tmpImg = Path.GetTempFileName();
                image.Save(tmpImg);
                IPicture newArt = new Picture(tmpImg);
                tagFile.Tag.Pictures = new IPicture[1] {newArt};
            }

            tagFile.Save();

        }
        catch (Exception e) 
        { 
            _logger.Log(e); 
        }
    }

И код, используемый для воспроизведения дорожки в программном обеспечении (FilgraphManager в QuartzTypeLib):

public void Play()
    {
        if (!_isPaused)
        {
            _graphManager = new FilgraphManager();
            _mp3control = (IMediaControl)_graphManager;
            _mp3position = (IMediaPosition)_graphManager;
            _tempFile = Path.GetTempFileName();
            File.Copy(_fullPath, _tempFile, true);  

            _mp3control.RenderFile(_tempFile);
        }
        else
        {
            _isPaused = false;
        }
        _mp3control.Run();
    }

И ошибка при выполнении _mp3control.RenderFile(_tempFile):

{System.Runtime.InteropServices.ExternalException} = {"Exception from HRESULT: 0x80040266"}
at QuartzTypeLib.FilgraphManagerClass.RenderFile(String strFilename)

Моя самая большая проблема здесь заключается в том, что я не знаю, связана ли ошибка с (нашей реализацией) FFmpeg (большая библиотека, которая отлично используетсяво многих других местах), TagLib-Sharp или воспроизводимого аудио.

Редактировать 1: Следуя совету Дж. Эндрю Лафлина, я смотрел на различия тэгов ID3 ​​в гексах каждого файла,Вот что я нашел:

Исходный ввод - ID3v2.3.После перекодирования с помощью FFmpeg данные ID3 будут v2.4.Этот исходный перекодированный файл прекрасно воспроизводится в медиа-плеерах и нашем программном обеспечении.Использование TagLib # в нашем программном обеспечении для добавления обложек альбомов сохраняет ID3v2.4, но теги доступны только при использовании TagLib # для их чтения и воспроизводятся только в медиаплеерах, таких как Windows Media Player.Использование другого инструмента для изменения тегов ID3 ​​(в данном случае AudioShell Tag Editor) и добавления того же обложки альбома изменило версию ID3 до 2.3 и означало, что mp3 воспроизводится на нашем программном аудиоплеере, а также на других медиапроигрывателях. Однако изменение теговвпоследствии выдает исключение при сохранении изображения.

Еще одна вещь, которую я пытался, это полностью вырвать блок ID3v2.4 после перекодирования, это воспроизводится (как и следовало ожидать) во всех медиаплеерах.При использовании TagLib # для этого непомеченного файла теги были правильно применены (v2.3), и он продолжал нормально играть в нашем программном обеспечении, а также в других.

Если кто-то не может предложить элегантное решениеTagLib #, чтобы написать новый блок ID3v2.3 или вообще запретить FFmpeg писать один) Я думаю, что я могу просто программно удалить блок ID3v2.4 из файла после кодирования, а затем написать новый.

1 Ответ

3 голосов
/ 24 июля 2011

TagLib # может использоваться для «понижения» тэга ID3 с 2.4 до 2.3. Я лично предпочитаю конвертировать мои теги ID3 в 2.3, поскольку они более последовательно применяются в музыкальных проигрывателях.

Это было давно, но я полагаю, что вы можете использовать следующее в приведенном выше коде:

TagLib.Id3v2.Tag id3v2tag = tagFile.GetTag(TagLib.TagTypes.Id3v2, false);

if(id3v2tag != null)
    id3v2tag.Version = 3;

tagFile.Save();

В качестве альтернативы, вы можете заставить все теги отображаться в 2.3, используя следующий код при инициализации вашего приложения:

TagLib.Id3v2.Tag.DefaultVersion = 3;
TagLib.Id3v2.Tag.ForceDefaultVersion = true;

TagLib # также может полностью удалять теги и повторно добавлять их, но это не должно приводить к этому.

Удачи!

...