Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TMediaPlayer в потоке 
V
    Опции темы
livo
Дата 18.11.2010, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Здравствуйте! Пишу свой аудиоплеер, используя TMediaPlayer как основу. Сделал плейлист, в котором отображается номер файла, его имя и длина в минутах и секундах.
После загрузки списка файлов запускается поток, в котором создается объект TMediaPlayer, определяющий длину каждого звукового файла из списка.
Все бы ничего, но конструктор TMediaPlayer требует в качестве параметра либо указатель на родительский компонент, либо дескриптор родительского окна. В случае передачи в конструктор NULL не срабатывает метод Open() TMediaPlayer"а, а если передать дескриптор  главной формы, то возникают проблемы с этим окном: например, при изменении размера окна у меня выдавалось сообщение о недостаточном объеме памяти для завершения операции.

Вот код потока:
Код

//заголовочный файл
//---------------------------------------------------------------------------
#ifndef UTTrackLengthThreadH
#define UTTrackLengthThreadH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <MPlayer.hpp>
//---------------------------------------------------------------------------
class TTrackLengthThread : public TThread
{            
private:
protected:
        void __fastcall Execute();
        String path_mod;//недостающая часть пути к файлам списка
        int track_length,cur_index;//используються в syncSetTLength
        TStringList *sl_files;//список файлов для обработки в виде "<путь или часть пути>|<псевдоним>"
        TMediaPlayer *mp;
        void __fastcall syncSetTLength();//синхронное обновление информации
public:
        __fastcall TTrackLengthThread(bool CreateSuspended,HANDLE ahandle,TStrings *files,String add_to_path);
};
#endif

Код

//кодовый модуль потока
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UTTrackLengthThread.h"
#include "AudioU.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TTrackLengthThread::TTrackLengthThread(bool CreateSuspended,
                HANDLE ahandle,TStrings *files,String add_to_path)
        : TThread(CreateSuspended)
{
 track_length=0; 
 sl_files=new TStringList;
 mp=new TMediaPlayer(ahandle);
 sl_files->AddStrings(files);
 path_mod=add_to_path;
 Priority=tpIdle;
}
//---------------------------------------------------------------------------
void __fastcall TTrackLengthThread::Execute()
{
 int pos;
 for(cur_index=0; cur_index<sl_files->Count; cur_index++)
 {
   if(Terminated)break;
   if(sl_files->Objects[cur_index])continue;
   String fn=path_mod+sl_files->Strings[cur_index],
          ext="";
   pos=fn.Pos("|");
   if(pos)fn=fn.SubString(1,pos-1);
   ext=ExtractFileExt(fn).LowerCase();
   if(ext==".mid" || ext==".midi" || ext==".kar" || ext==".cda")continue;
   mp->FileName=fn;
   mp->Open();
   track_length=mp->Length;
   mp->Close();
   Synchronize(syncSetTLength);
 }
 delete mp;
 delete sl_files;
}
//---------------------------------------------------------------------------
void __fastcall TTrackLengthThread::syncSetTLength()
{
 String sls=sl_files->Strings[cur_index];
 int ii=Form1->lstPlayList->Items->IndexOf(sls);
 if(ii!=-1)
 {
   Form1->lstPlayList->Items->Objects[ii]=(TObject*)track_length;
   Form1->lstPlayList->RepaintItem(ii);
 }
}


И еще вот функции, работающие с этим потоком:
Код

//создание потока
void __fastcall TForm1::track_length_updating()
{
 track_length_updating_stop();
 tlen_thread=new TTrackLengthThread(1,Handle,lstPlayList->Items,sCheckBoxReadDirProg->Checked?dirmusic:String(""));
 tlen_thread->Resume();
}
//---------------------------------------------------------------------------
//остановка и удаление потока
void __fastcall TForm1::track_length_updating_stop()
{
 if(tlen_thread)
 {
   tlen_thread->Terminate();
   tlen_thread->WaitFor();
   delete tlen_thread;
   tlen_thread=0;
 }
}
//---------------------------------------------------------------------------


Это сообщение отредактировал(а) livo - 18.11.2010, 12:28
PM MAIL   Вверх
xvr
Дата 18.11.2010, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



VCL'ные визуальные объекты расчитанны на работу ТОЛЬКО из главного потока (там где был main). У вас TMediaPlayer создается в главном потоке, запускается в отдельном потоке, а парентом вы ему хотите передать вообще нечто  smile 
Цитата(livo @  18.11.2010,  12:20 Найти цитируемый пост)
не срабатывает метод Open()
И только он? Вам повезло  smile 


PM MAIL   Вверх
livo
Дата 18.11.2010, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Тогда как можно организовать работу TMediaPlayer"а в потоке, чтобы все работало корректно?
Мне нужно только узнать время звучания звуковых дорожек.
PM MAIL   Вверх
Alexeis
Дата 18.11.2010, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(livo @  18.11.2010,  16:53 Найти цитируемый пост)
 TMediaPlayer
 использует интерфейс MCI http://msdn.microsoft.com/en-us/library/dd...v=VS.85%29.aspx
  Можно посмотреть чего какой минимум MCI команд нужен и реализовать и реализовать в обход его. 



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
xvr
Дата 18.11.2010, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 48
Всего: 223



Цитата(livo @  18.11.2010,  15:53 Найти цитируемый пост)
Тогда как можно организовать работу TMediaPlayer"а в потоке, чтобы все работало корректно?

Никак. TMediaPlayer это визуальный компонент, обертка над MCI (см сообщение  Alexeis). Без родительской формы он работать не будет.
А почему вам нужно именно в потоке? А в нормальном виде чем не устраивает?

PM MAIL   Вверх
livo
Дата 18.11.2010, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Alexeis, спасибо, попробую вручную использовать MCI.
xvr, подсчет длительностей звучания дорожек нужно делать только в потоке. Если сделать иначе, то скажем при добавлении 1000 файлов можно идти попить чайку, а после садиться слушать музыку.
PM MAIL   Вверх
SVN74
Дата 18.11.2010, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 740
Регистрация: 5.5.2008
Где: Комсомольск на Дн епре

Репутация: 11
Всего: 18



Цитата(livo @  18.11.2010,  12:20 Найти цитируемый пост)
Все бы ничего, но конструктор TMediaPlayer требует в качестве параметра либо указатель на родительский компонент, либо дескриптор родительского окна.

TMediaPlayer *MyPlay = new TMediaPlayer(Application);

Это сообщение отредактировал(а) SVN74 - 18.11.2010, 20:47
PM MAIL WWW   Вверх
livo
Дата 19.11.2010, 00:46 (ссылка) |   (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Цитата(SVN74 @  18.11.2010,  20:45 Найти цитируемый пост)
TMediaPlayer *MyPlay = new TMediaPlayer(Application);

Метод Open() не срабатывает.

Используя MCI в обход TMediaPlayer"а мне удалось решить задачу. Вот функция, которая вычисляет длину звукового файла. Значения верные для wav,wma,mp3; для других форматов не проверял. Результат в миллисекундах.
Код

unsigned __fastcall TTrackLengthThread::mci_get_length(String filename)
{
 unsigned length=0;
 TMCI_Open_Parms OpenParm; memset(&OpenParm,0,sizeof(OpenParm));
 OpenParm.lpstrElementName = filename.c_str();
 if(!mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, (unsigned)&OpenParm))
 {
   //получение длины
   TMCI_Status_Parms StatusParm; memset(&StatusParm,0,sizeof(StatusParm));
   StatusParm.dwItem = MCI_STATUS_LENGTH;
   mciSendCommand(OpenParm.wDeviceID,MCI_STATUS,MCI_WAIT|MCI_STATUS_ITEM, (unsigned)&StatusParm);
   length=StatusParm.dwReturn;
   //закрытие
   mciSendCommand(OpenParm.wDeviceID,MCI_CLOSE,0,0);
 }
 return length;
}

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0930 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.