Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [delphi] "Suonare" un file: niente errori ma niente audio

    ciao gente,
    stavo cercando di far suonare un file audio nel programma, solo che NON suona!!!

    ho un componente FileListView che mostra il contenuto delle cartelle che contengono dei files audio...
    vorrei che al doppio click partisse il file, solo che se doppio clicco il pulsante PLAY diventa attivo, MA non si sente nulla!

    codice:
    Player.FileName:=listato.Items.item[listato.Selected.Index].Caption;
    Player.Open;
    Player.Play;
    listato contiene i files
    player è il controllo TMediaPlayer
    dalla prima riga di codice ottengo una cosa del genere:
    Player.Filename:="NomeFile"

    che cos'è che non va, secondo voi?

    grazie

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477
    Vediamo come va a finire questa...

    Innanzitutto, la forma che hai usato riportata qui sotto
    codice:
    Player.FileName:=listato.Items.item[listato.Selected.Index].Caption;
    è inutilmente ridondante, poichè sarebbe sufficiente scrivere
    codice:
    Player.FileName := Listato.Selected.Caption;
    dopo aver aggiunto anche il seguente controllo
    codice:
    if Listato.Selected <> nil then
      Player.FileName := Listato.Selected.Caption;
    altrimenti ottieni un Access Violation se nessun elemento è selezionato e fai doppio clic sul controllo.

    Poi, il MediaPlayer non funziona poichè la proprietà Caption dalla quale estrai il nome del file ti restituisce appunto solo il nome, ma il componente TMediaPlayer vuole il percorso completo nella proprietà FileName (C:\Percorso\NomeFile.wav, ad esempio).
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    innnanzitutto grazie.
    Poi, il MediaPlayer non funziona poichè la proprietà Caption dalla quale estrai il nome del file ti restituisce appunto solo il nome, ma il componente TMediaPlayer vuole il percorso completo nella proprietà FileName (C:\Percorso\NomeFile.wav, ad esempio).
    prima di postare il topic avevo anche pensato al problema da te proposto, solo che anche facendo una cosa tipo:

    codice:
    nomefile:=listato.Items.item[listato.Selected.Index].Caption;
    Player.FileName:=ExtractFilePath(Parm(0) + 'cartella suoni\ + nomefile + '.wav');
    non parte cmq il sonoro.

    tieni conto che ho usato il codice ridondante per far capire come avevo lavorato io e che cmq il file che ho provato ad usare è in realtà contenuto in varie sottocartelle e speravo che con ExtractFilePath... sarei riuscito a farlgi trovare il file cercato...


  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477
    Originariamente inviato da Lyll0
    prima di postare il topic avevo anche pensato al problema da te proposto
    Ogni volta che scrivo una soluzione salta sempre fuori che l'hai già pensata...che strano.

    Originariamente inviato da Lyll0
    solo che anche facendo una cosa tipo:
    codice:
    nomefile:=listato.Items.item[listato.Selected.Index].Caption;
    Player.FileName:=ExtractFilePath(Parm(0) + 'cartella suoni\ + nomefile + '.wav');
    non parte cmq il sonoro.
    Non parte per forza di cose: comunque, potresti iniziare a correggere la riga in cui assegni il valore a nomefile seguendo i suggerimenti che ti ho indicato io.
    In secondo luogo, la funzione ExtractFilePath non c'entra proprio nulla in questo problema.

    Originariamente inviato da Lyll0
    tieni conto che ho usato il codice ridondante per far capire come avevo lavorato io
    Cioè, come hai lavorato? A te serve innanzitutto ottenere l'elemento selezionato, quindi l'istruzione Listato.Selected te lo restituisce già direttamente, senza il bisogno di prelevare l'indice di questo elemento per applicarlo alla proprietà Items.Item ottenendo ancora lo stesso elemento di cui avevi già ottenuto un riferimento prima; è un'operazione inutile, ridondante e non significa nulla o non rappresenta alcun modo di lavorare se non un modo sbagliato o comunque confuso, quindi togli quella ripetizione e usa il codice che ti ho scritto nella prima risposta.

    Originariamente inviato da Lyll0
    e che cmq il file che ho provato ad usare è in realtà contenuto in varie sottocartelle e speravo che con ExtractFilePath... sarei riuscito a farlgi trovare il file cercato...
    Non per ripetere sempre le solite cose, ma posso accertarti che con la "speranza" si ottiene poco nel mondo della programmazione; non puoi sperare che una funzione faccia ciò che ti serve: devi documentarti sul suo comportamento e *capire* come funziona.

    Poi, non venirmi a dire che leggi la Guida in linea, visto che premendo il tasto F1 sull'istruzione ExtractFilePath appare istantaneamente l'argomento relativo che spiega per filo e per segno a cosa serve quella funzione e cosa ti restituisce.

    Visto che non vuoi leggerla, ti riporto direttamente qui il testo della Guida:

    ExtractFilePath
    The resulting string is the leftmost characters of FileName, up to and including the colon or backslash that separates the path information from the name and extension. The resulting string is empty if FileName contains no drive and directory parts.


    La traduco pure: la stringa risultante è costituita dai caratteri più a sinistra di FileName (che è il parametro passato) fino a - e incluso - i due punti o il backslash ("\") che separa il percorso da nome ed estensione. La stringa risultante è vuota se il parametro FileName non contiene unità o parti di directory.

    Scusa se insisto, sfoceremo nella sola discussione, ma sei poi tu che ti offendi sostenendo che fai tutto ciò che ti dico come leggere la Guida e correggere le istruzioni, poi alla fine della discussione il problema si sposta, il codice rimane uguale e seguono a ruota le solite diatribe sul fatto che io tratterei male la gente.

    Scusa eh, sono le 3 di notte, io ti rispondo per aiutarti e tu ogni volta ignori i miei suggerimenti...mi piacerebbe capire perchè scrivi le domande a questo punto.

    Tornando a noi, prelevando la Caption dall'elemento selezionato dal controllo FileListView, se fai il debug, ti accorgerai che ottieni solamente il nome del file. La funzione ExtractFilePath, così come dice la Guida, estrae la parte relativa all'unità e al percorso dal nome di file completo passato come parametro, che però deve includere un'unità e un percorso, altrimenti - sempre come detto dalla Guida - la stringa risultante è vuota.

    Ritornando al codice che hai postato:
    codice:
    Player.FileName:=ExtractFilePath(Parm(0) + 'cartella suoni\ + nomefile + '.wav');
    Tu unisci il nome del file ad un'estensione che potrebbe essere già inclusa nel nome stesso (dipende dalle impostazioni locali del sistema, quindi il codice potrebbe non funzionare in sistemi in cui la visualizzazione delle estensioni è abilitata); in secondo luogo, accodi il nome del file presumibilmente completo a questa fantomatica variabile "Parm", che forse è ParamStr (non capisco come fai a fare un copia e incolla ottenendo un testo diverso dall'originale), a cui aggiungi infine il percorso "cartella suoni". A questo punto, hai costruito il percorso completo del file, ma magicamente passi alla proprietà FileName del player solo la directory orfana del nome del file perchè hai usato ExtractFilePath che non funziona come ti aspettavi (ma come ti dicevo, c'è poca speranza nella programmazione), bensì ti elimina la parte del nome del file dalla stringa.

    Io comunque non userei FileListView dato che i file multimediali sono contenuti - apparentemente - in un percorso ben determinato e fisso ("cartella suoni")...se invece desideri specificare un nome di file presente in una cartella devi poter navigare nel controllo; gestendo la riproduzione nel doppio click, ogni volta che tenti di subentrare in una sottocartella il Player prova a riprodurre la cartella come file multimediale.
    Magari usa una OpenDialog al suo posto, che ti permette di esplorare tutto il disco usando la finestra comune a tutti i programmi e quindi famigliare, tenendo conto che la proprietà FileName contiene già il percorso completo del file da riprodurre, indipendentemente dalle impostazioni del sistema, che puoi usare subito passandola alla proprietà FileName del Player oppure memorizzare il percorso in un file di impostazioni.

    Posto un esempio di codice, poi più di così credo che non ci sia nulla da dire, ma ho come la vaga impressione che il prossimo messaggio sarà identico ai precedenti, con gli stessi errori (che trovano ogni volta una giustificazione diversa, invece di essere corretti adeguatamente).

    codice:
    procedure TDemoForm.SelAndPlayButtonClick(Sender: TObject);
    begin
      if OpenDialog.Execute then
      begin
        MediaPlayer.FileName := OpenDialog.FileName;
        MediaPlayer.Play;
      end;
    end;
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477
    Rettifico il codice riportato sopra (non avevo la possibilità di verificarlo quando ho scritto il messaggio): manca la chiamata al metodo Open del controllo TMediaPlayer, senza quella chiamata non è possibile aprire il dispositivo MCI appropriato per il file selezionato per riprodurlo successivamente.

    codice:
    procedure TDemoForm.SelAndPlayButtonClick(Sender: TObject);
    begin
      if OpenDialog.Execute then
      begin
        MediaPlayer.FileName := OpenDialog.FileName;
        MediaPlayer.Open;
        MediaPlayer.Play;
      end;
    end;
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  6. #6
    grazie.

    non volevo usare OpenDialog perchè mi serviva una treeview per compattare tutto in un'unica finestra senza cose esterne.

    PS: per gli altri utenti del forum:
    non spaventatevi. alka fa così, ma in fondo è buono e cerca di aiutare.
    sono io che lo irrito!

  7. #7
    per gli utenti.

    se non avete grosse pretese ma, come nel mio caso, vi serve solo un riproduttore di suoni .WAV su Torry.net trovate dei componenti molto comodi. io ho scaricato PDJSound che va bene per Delphi 6 ma anche 7.

    per quel che mi riguarda ho trovato un player molto semplice da usare che supporta un path stringa e dunque consente di utilizzare una lista di canzoni senza dovedr usare un Open Dialog.

    il comando PlaySound() è scomodo perchè il primo parametro da passare è il nome del file ma può solo essere fornito come 'path'.
    quindi per dare effetti ad un controllo (tipo click.wav su pulsante) è comodo e veloce, ma non consente di sfruttare path complessi creati con procedure esterne.

    ciao gente!

  8. #8
    volevo notificare agli utenti un'altra cosa.
    visto che i wav erano troppo grandi sono tornato indietro al componente TMediaPlayer che supporta anche i file mp3.



  9. #9
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,477
    Originariamente inviato da Lyll0
    il comando PlaySound() è scomodo perchè il primo parametro da passare è il nome del file ma può solo essere fornito come 'path'.
    quindi per dare effetti ad un controllo (tipo click.wav su pulsante) è comodo e veloce, ma non consente di sfruttare path complessi creati con procedure esterne.
    Queste affermazioni sono false.

    La funzione API PlaySound non ha alcuna limitazione sul percorso; è in grado di riprodurre qualsiasi risorsa sonora in formato WAVE sia da file esterni, sia da risorse incorporate nella applicazione stessa oppure dal sistema usando una delle costanti predefinite che rappresentano un evento (avvio, arresto, minimizza, ripristino, errore...).

    La funzione PlaySound, come tutte le funzioni API, accetta stringhe di testo null terminated, cioè terminate da un carattere nullo (codice 0, zero). Le stringhe in Delphi sono strutture dati gestite dinamicamente e di gran lunga più complesse, pertanto è necessario eseguire un "casting" per informare Delphi che la stringa da passare deve figurare così come descritto sopra.

    Per fortuna, questa operazione non richiede allocazioni di buffer manuali o altro...basta semplicemente "castare" la stringa al tipo PChar (puntatore a carattere), che è equivalente poi al PAnsiChar.

    Un esempio:
    codice:
    procedure TDemoForm.PlayButtonClick(Sender: TObject);
    var
      Path: string;
    begin
      Path := 'C:\Cartella\Sottocartella\NomeFile.wav';
      PlaySound(PChar(Path), 0, SND_FILENAME);
    end;
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  10. #10
    buono a sapersi, grazie.

    l'ho detto perchè anche cercando in rete non avevo trovato un metodo per convertire la stringa in PChar.
    :metallica

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.