




Несколько лет назад я написал свой собственный для этой цели. Вы можете написать эффективную клиентскую сторону, используя flash. Ключевые моменты, которые я помню:
Обновлено: я понимаю, что вы хотели сделать это с .Net, но на самом деле может быть более полезно знать сторону клиента, прежде чем загружать файл на сервер, как если бы вы хотите наложить ограничения на длину файла, вы можете сделать это намного раньше в процессе.
Наконечник для вспышки пригодится в будущем, поскольку мне приходилось иметь дело с этим в прошлом, и я действительно столкнулся с неправильными показаниями продолжительности, которые испортили бы скруббер. Спасибо!
[мое собственное решение]
Я добавил второй элемент управления медиаэлементом, который я использую, чтобы открывать каждый mp3-файл в списке и получать его NaturalDuration. Откройте и закройте каждый файл в списке и просуммируйте все значения.
Как утверждают другие, заголовки mp3 неточны. Медиаэлемент обеспечивает правильную продолжительность.
Вероятно, это не самый быстрый метод, но в моем случае самый простой (он не полагается на другие библиотеки).
Я обернул библиотеку mp3-декодера и сделал ее доступной для разработчиков .net. Вы можете найти это здесь:
http://sourceforge.net/projects/mpg123net/
Включены образцы для преобразования файлов mp3 в PCM и чтения тегов ID3.
Я предполагаю, что его можно использовать для правильного расчета длительности mp3 файла.
После того, как много теоретизирования, я нашел способ правильно и неоспоримо вычислить длительность mp3-файл.
Позвольте мне сначала повторить, почему стандартные методы, описанные выше, не работают:
Метод ID3: не все файлы имеют теги id3, и если они есть, то в них может не быть задано поле продолжительности.
Оценка по чтению одного кадра * размер файла: не сработает для файлов VBR.
Заголовок Xing: он есть не во всех файлах.
Расшифровка и определение по размеру PCM: у меня есть файл размером 3+ ГБ, не буду ждать, пока он декодируется.
Я читаю везде, и все ведет в NAudio. Марк, СПАСИБО за хорошие усилия и чистый исходник! Однако метод, который чаще всего предлагается с NAudio, - это прочитать файл с помощью Mp3FileReader и получить все кадры. Проблема: Mp3FileReader создает оглавление в начале, и это занимает вечность, даже для небольших файлов всего за ОДИН день :)
Марк предложил мне удалить создание оглавления, поскольку исходный код доступен, и при этом я нашел гораздо более простой метод. Вот; это говорит само за себя:
double GetMediaDuration(string MediaFilename)
{
double duration = 0.0;
using (FileStream fs = File.OpenRead(MediaFilename))
{
Mp3Frame frame = Mp3Frame.LoadFromStream(fs);
if (frame != null)
{
_sampleFrequency = (uint)frame.SampleRate;
}
while (frame != null)
{
if (frame.ChannelMode == ChannelMode.Mono)
{
duration += (double)frame.SampleCount * 2.0 / (double)frame.SampleRate;
}
else
{
duration += (double)frame.SampleCount * 4.0 / (double)frame.SampleRate;
}
frame = Mp3Frame.LoadFromStream(fs);
}
}
return duration;
}
Кстати, он рассчитал точную продолжительность файла, который составлял 9 дней 18 часов, менее чем за минуту (на самом деле он будет делать это так быстро, как диск может прочитать файл, поскольку он использует ОЧЕНЬ МАЛЕНЬКИЙ ЦП).
В моем случае это вычислило продолжительность в четыре раза больше фактической продолжительности для всех файлов, с которыми я работал (кстати, все они были стерео-файлами). Возможно, что-то изменилось в NAudio с момента этого ответа, но я не уверен, что * 4.0 необходим, по крайней мере, в случае файлов, с которыми я тестировал. Тем не менее, я ценю ответ, он помог мне на 99% пути.
@JaredPhelps, у вас было несколько минут экспериментов и одна константа :)
Я думаю, что @JaredPhelps верен, умножать SampleCount на 2 или 4 не нужно. По крайней мере, для файла, который я тестировал, когда я удалил его, продолжительность оказалась правильной.
@ DanielMošmondor, не могли бы вы пояснить, что вы имеете в виду? Что мне не хватало?
Есть ли у вас похожая функция для файлов WMA?
@AbeMiessler, это был бы отличный новый вопрос, не так ли?
@ DanielMošmondor, да, будет! stackoverflow.com/questions/16107774/…
привет @ DanielMošmondor, может я знаю тип "_sampleFrequency", который дает мне ошибку.
_sampleFrequency, кажется, тусуется и ничего не делает ...?
Ответ из более позднего дубликата показывает самый простой способ в 2015 году: stackoverflow.com/a/34518350/1860652