Реализация очереди с использованием двух стеков в Swift:
struct Stack<Element> {
var items = [Element]()
var count : Int {
return items.count
}
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element? {
return items.removeLast()
}
func peek() -> Element? {
return items.last
}
}
struct Queue<Element> {
var inStack = Stack<Element>()
var outStack = Stack<Element>()
mutating func enqueue(_ item: Element) {
inStack.push(item)
}
mutating func dequeue() -> Element? {
fillOutStack()
return outStack.pop()
}
mutating func peek() -> Element? {
fillOutStack()
return outStack.peek()
}
private mutating func fillOutStack() {
if outStack.count == 0 {
while inStack.count != 0 {
outStack.push(inStack.pop()!)
}
}
}
}
Вы можете рассчитать продолжительность, разделив размер файла на скорость передачи данных. Вы можете получить битрейт из одного из заголовков кадра. Конечно, это не сработает для файлов MP3 с переменной скоростью, где вы можете иметь разную скорость для каждого кадра.
Использование макета заголовка (это всего четыре байта):
Откройте MP3 в потоке
Найдите начало заголовка первого кадра, читая, пока вы найти заголовок синхронизации, в котором 11 последовательных битов установлены на 1. Это раньше было 12, но было изменено, чтобы разрешить использование MPEG версии 2.5.
Определите идентификатор версии MPEG. Для определения скорости передачи данных V2.5 совпадает с V2
Определить описание уровня
Считать индекс скорости передачи данных
Используя версию MPEG, описание уровня и индекс скорости передачи данных, определите фактический скорость передачи данных из таблицы индексов скорости передачи данных в ссылке на связанный заголовок
Разделите размер файла в килобитах ((8 * размер в байтах) / 1000) на скорость передачи данных, чтобы получить продолжительность в секундах
Я не мог найдите пример Delphi, но вот реализация C # , в которой этот метод используется в справочных целях. См. Метод getLengthInSeconds.
Не уверен, что это сработает, но я нашел это сообщение на форуме . Я бы сравнил результаты с чем-то вроде winamp, чтобы убедиться, что он работает.
Mp3 делятся на кадры следующим образом
Вам нужно будет подсчитать количество кадров
В Windows есть достаточно эффективный способ определения длины MP3-файла.
Это серьезная уловка, но, похоже, работает.
Райан.
//add MPlayer to the uses clause;
//
//add the MP3PlayLength function to an existing form and
//place a button on the form, linking the button click method to see how it works.
uses MPlayer;
function TForm1.MP3PlayLength(aMP3FileName:string):string;
var
wMP : TMediaPlayer;
wLen : Cardinal;
begin
Try
wMP := TMediaPlayer.Create(self);
try
wMP.Visible := false;
wMP.parent := self;
wMP.FileName := aMP3FileName;
wMP.TimeFormat := tfMilliseconds;
wMP.DeviceType := dtAutoSelect;
wMP.Open;
try
wLen := trunc(wMP.Length / 1000);
result := inttostr(wLen div 60)+':'+inttostr(wLen mod 60);
finally
wMP.Close;
end;
finally
wMP.free;
end;
except
result := '(err)';
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
showmessage(MP3PlayLength(OpenDialog1.FileName));
end;
Или попробуйте MediaInfo.dll текст ссылки .
Он включает класс оболочки Delphi. Например:
MediaInfo_Get(Handle, Stream_General, 0, 'Duration', Info_Text, Info_Name)
Другое решение DSPack текст ссылки
size := FilterGraph.Duration;
Я рекомендую вам использовать BASS
http://www.un4seen.com/bass.html
BASS - это аудио библиотека .. чтобы предоставить разработчикам мощный поток (MP3 .. OGG ..) функции. Все это в крошечной DLL размером менее 100 КБ.
это очень просто использовать
uses BASS;
var
playingChannel: HSTREAM;
playingLength: Double;
mp3filename: String;
begin
BASS_Init(-1,44100,0,Application.Handle,nil);
playingChannel:=BASS_StreamCreateFile(FALSE,pchar(mp3filename),0,0,0);
playingLength:=BASS_ChannelBytes2Seconds(playingChannel,
BASS_ChannelGetLength(playingChannel,BASS_POS_BYTE));
end;
Зайдите на www.un4seen.com и скачайте библиотеку басов, вы получите много информация из раздела форума. ;)
Я давно не играл с Dephi.
Попробуйте,
FileSize(var aFile)
Оформить заказ в этом блоге, используя FFMPEG для фонового обходного пути в проекте Ruby.