IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Solution de capture flux Audio et Video en C# [Débutant]


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Points : 13
    Points
    13
    Par défaut Solution de capture flux Audio et Video en C#
    Bonjour,

    Mon but est de faire une application de gestion de vidéos (tri) avec la possibilité d'un enregistrer via une webcam.

    Je me suis lancé dans la programmation de mon appli en C# pensant que le langage était adapté, mais après une grosse journée de recherche (8h devant google), je me rend compte que ce n'est peut-être pas le cas.

    Donc je cherche à enregistrer simplement le flux vidéo et audio d'une webcam puis créer un fichier.avi ou autre. L'important étant qu'un fichier soit enregistré et que je puisse définir les compressions pour gérer le poids du fichier.

    Pour enregistrer le flux vidéo, j'ai téléchargé AForge.net, qui est très sympa mais ne me permet pas de capturer le son.
    Et ensuite je n'ai rien trouver de vraiment précis. Je me suis tourné vers la possibilité d'utiliser DirectShow et DirectSound mais la version de DirectX SDK en téléchargement sur le site de MS à l'air d'être que pour le C++, je n'arrive pas à implémenter les library dans mon projet C#.

    Et je dois avouer que je suis un gros débutant (très motivé), mais débutant quand même, donc je ne sais pas si il est possible de capturer le flux vidéo avec Aforge par exemple et simultanément de capturer l'audio avec une autre library puis d'assembler les deux.

    Donc en fait je suis assez dans le flou concernant mes possibilités, donc je suis preneur de toutes idées ou solutions ou conseils. N'importe quoi qui pourrait m'aider à réaliser mon appli.

    Merci

  2. #2
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    salut

    tu peux utiliser Slimdx (www.slimdx.org) qui est un "wrapper" .Net au dessus de DirectX 10/11 et qui permet l'utilisation de directX en C# sans faire de C++...

    Sinon, effectivement, avec AForge.Net, tu vas capturer la vidéo, pas le son. Mais je pense que la question relative au son doit etre évoquer sur les forums de Aforge.Net

    Voilà

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Points : 13
    Points
    13
    Par défaut
    Merci pour ta réponse.

    Je suis en train d'essayer plusieurs choses avec SlimdDX, en effet.
    J'ai essayé d'utiliser la library Alvas, mais par manque de Docs, je suis pas allé très loin.

    Je crée mon WaveFormat et mon buffer avec le Device voulue, mais je bloque pour enregistrer le son dans un .wav.

    J'essaie avec FileStream de System.IO et WaveStream de SlimDX mais il doit avoir un truc que je pige pas.

    Voila une partie de mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     this.captureDevice = new DirectSoundCapture(this.listDevices[this.cboSoundDevice.SelectedIndex].DriverGuid);
     
                WaveFormat waveFormat = new WaveFormat();
                waveFormat.FormatTag = WaveFormatTag.IeeeFloat;
                waveFormat.BitsPerSample = 32;
                waveFormat.BlockAlignment = (short)(waveFormat.BitsPerSample / 8);
                waveFormat.Channels = 1;
                waveFormat.SamplesPerSecond = 44100;
                waveFormat.AverageBytesPerSecond = waveFormat.SamplesPerSecond * waveFormat.BlockAlignment * waveFormat.Channels;
     
                CaptureBufferDescription bufferDescription = new CaptureBufferDescription();
                bufferDescription.BufferBytes = 8192;
                bufferDescription.Format = waveFormat;
                bufferDescription.WaveMapped = false;
     
                CaptureBuffer buffer = new CaptureBuffer(this.captureDevice, bufferDescription);      
                this.fs = new FileStream(Constante.CHEMINMEDIA + Constante.CHEMINFICHIER + "essai_audio.wav",FileMode.Create);     
                buffer.Start(true);
    Et en fait c'est là que je bloque. Je ne sais pas comment utiliser les classes
    FileStream ou WaveStream pour enregistrer. J'ai essayer beaucoup de choses provenant de tuto, mais pour l'instant, choux blanc...

  4. #4
    Expert confirmé

    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2006
    Messages
    3 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 580
    Points : 5 194
    Points
    5 194
    Par défaut
    Je ne me souviens pas comment je faisais mais de mémoire,

    avec DirectX, tu récupères les buffers de données provenant de la carte son, et ensuite avec le filestream, tu utilises une méthode d'ajout d'octet et le tour est joué.

    On trouve plein de tutoriaux pour enregistrer du son en C# (pas forcément avec DirectX, souvent avec Winmmi si je me souviens bien)...

    Bon courage (t surement plus très loin du résultat)

    T'as cherché sur le forum Aforge.net pour le son ?

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Points : 13
    Points
    13
    Par défaut
    Merci pour ta réponse.

    Oui sur le forum d'Aforge j'ai cherché, et pas de réponse, sauf que AForge ne propose aucune option pour l'instant concernant le son.

    Sinon le soucis est que tous les exemples sur le net utilise la library DirectX qui n'est plus compatible maintenant, et SlimDX ou autre ne sont pas exactement pareil.
    Alors je sais qu'il doit bien avoir une solution mais pour quelqu'un comme moi qui ne s'y connait pas trop dans le son, je galère un peu.

    En fait d'après ce que j'ai trouvé, j'y suis presque oui, mais j'ai juste du mal a enregistrer le son.
    Si je résume, j'ai mon objet SoundCaptureDevice (Capture pour DirectX) qui est ma source de son.
    J'instancie WaveFormat avec lequel je paramètre le son que je veux récupéré (je sais c'est flou, mais ce que j'ai compris).
    Ensuite je crée mon objet CaptureBufferDescription pour paramétrer mon buffer que j'instancie avec mon SoundCaptureDevice et mon CaptureBufferDescription.

    Alors déjà là j'ai pas vraiment réussit à avoir une description simple du buffer. Je sais que que c'est un espace alloué dans la mémoire. D'après ce que je peux deviner, c'est l'endroit ou va être stocké le son qui provient du micro. C'est pas trop technique comme termes... Désolé.

    Donc ensuite dans ma logique, il faut maintenant enregistrer ce qui est dans le buffer et d'après ce que j'ai vu ce sont des bytes.

    Et pour enregistrer, j'ai filestream et WaveStream. Vu que j'utilise SlimDx, je me suis dis autant essayer de l'utiliser jusqu'au bout, donc je dispose des méthodes:

    1)BeginWrite(array<Byte>[], Int32, Int32, AsyncCallback, Object)

    byte[] buffer,
    int offset,
    int count,
    AsyncCallback callback,
    Object state

    2)WriteByte(Byte)
    byte value

    Et c'est là ou je coince. La première je ne pige pas trop les paramètres à utilisé, et la deuxième je ne trouve pas comment envoyé des byte avec mon buffer, les méthodes ne le permettent pas directement en tout cas.

    Pour FileStream, je dispose de:

    Write(Array[], int, int)
    byte[] array,
    int offset,
    int count

    Et...Bah c'est un peu le même problème qu'au dessus.
    Dans les exemples que j'ai trouvé, les personnes déclarent un array de byte, mais il faut bien que je fasse quelque chose avec cet array, sinon j'ai du mal a comprendre comment il pourrait aider... Enfin je suppose que vous l'avez compris, c'est là ou je pige pas la manip


    Et bon je ne suis pas vraiment sur de mon code non plus, ça me parait très simpliste. Mais bon c'est un début, je vais déjà me concentrer avec ce code pour obtenir un résultat, on verra après l'amélioration et l'optimisation.

    Merci

  6. #6
    Membre éprouvé Avatar de miripesage
    Homme Profil pro
    gerant
    Inscrit en
    Novembre 2009
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : gerant
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2009
    Messages : 725
    Points : 1 156
    Points
    1 156
    Par défaut
    Bonsoir, jette un coup d'oeil ICI.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Points : 13
    Points
    13
    Par défaut
    Merci pour ta réponse. En ce qui concerne la vidéo, j'ai réussit à capturer des vidéos avec Aforge, donc je suis passé à l'enregistrement du son.

    Et j'ai pas encore réussit... J'ai découvert une nouvelle Library, NAUDIO, je vais essayer de m'y mettre.

    Sinon j'essai de m'inspirer de ceci :

    http://aaronamberman.com/tutorials/csaudio.php

    Un tuto assez complet qui utilise DirectX. Le seul problème est que je ne trouve pas l'équivalent sous SlimDX de certaines classes et méthodes. Comme par exemple BufferPositionNotify.

    Au final je me demande même si c'est pas l'accès à mon Device que je foire...

    j'affiche dans mon combobox les device:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Remplissage du combo Sound Device
            private void FillincboSoundDevices()
            {
                DeviceCollection listDevices = DirectSoundCapture.GetDevices();
                foreach (DeviceInformation device in listDevices)
                {
                    this.cboSoundDevice.Items.Add(device.Description);
                }            
            }
    Et j'instancie DirectSoundCapture quand on choisit le Device dans le Combobox:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //Choix du device Sound
            private void cboSoundDevice_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (this.captureDevice == null)
                {
                    this.captureDevice = new DirectSoundCapture(this.listDevices[cboSoundDevice.SelectedIndex].DriverGuid);
                }
                else
                {
                    this.captureDevice.Dispose();
                    this.captureDevice = new DirectSoundCapture(this.listDevices[cboSoundDevice.SelectedIndex].DriverGuid);
                }           
            }
    Pour l'instant j'arrive à créer un fichier .wav qui lit un son... Metallique, strident, horrible quoi. A noter que le fichier .wav est d'une durée double voir triple à l'enregistrement. Donc je pense que j'ai aussi des soucis au niveau du réglage.

    Et je vous donne mon code qui capture le son. J'ai tellement la tête dedans que je vois surement plus des énormités, et ça coute rien de le mettre:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Diagnostics;
    //SlimDX
    using SlimDX.DirectSound;
    using SlimDX.Multimedia;
     
    namespace gdrm.Recorder
    {
        public class SoundRecord
        {
            //**********************************
            //********** Proprieté *************
            //**********************************
     
            private string fileName;
            private List<byte[]> rawSoundData;
            private bool record = false;
     
            private DirectSoundCapture soundCapture;
            private WaveFormat waveFormat;
            private CaptureBufferDescription bufferDescription;
            private CaptureBuffer buffer;
            private FileStream fileStream;
     
     
     
     
            //**********************************
            //********** Méthodes **************
            //**********************************
     
            // --- Constructeur ---
            public SoundRecord(string fileName, DirectSoundCapture soundCapture)
            {
                this.fileName = fileName;
     
                this.waveFormat = new WaveFormat();
                this.waveFormat.FormatTag = WaveFormatTag.Pcm;
                this.waveFormat.BitsPerSample = 16;
                this.waveFormat.BlockAlignment = (short)(waveFormat.BitsPerSample / 8);
                this.waveFormat.Channels = 1;
                this.waveFormat.SamplesPerSecond = 44100;
                this.waveFormat.AverageBytesPerSecond = waveFormat.SamplesPerSecond * waveFormat.BlockAlignment * waveFormat.Channels;
     
                this.bufferDescription = new CaptureBufferDescription();
                this.bufferDescription.BufferBytes = this.waveFormat.AverageBytesPerSecond;
                this.bufferDescription.ControlEffects = false;
                this.bufferDescription.Format = this.waveFormat;
                this.bufferDescription.WaveMapped = true;
     
                this.rawSoundData = new List<byte[]>();
     
                this.soundCapture = soundCapture;
                this.buffer = new CaptureBuffer(this.soundCapture, this.bufferDescription);
            }
     
            //--- Start Sound Record ---
            public void StartSoundRecord()
            {
     
                this.record = true;
                this.buffer.Start(true);
     
                while (this.record)
                {
                    this.rawSoundData.Add(BitConverter.GetBytes(this.buffer.CurrentCapturePosition));
                }        
            }
     
            //--- Stop sound Record ---
            public string StopSoundRecord()
            {
                this.record = false;
     
                if (!this.record)
                {
                    this.buffer.Stop();
                    this.buffer.Dispose();
     
                    List<byte> data = new List<byte>();
     
                    for (int a = 0; a < rawSoundData.Count; a++)
                    {
                        for (int b = 0; b < rawSoundData[a].Length; b++)
                        {
                            data.Add(rawSoundData[a].ElementAt<byte>(b));
                        }
                    }
                    this.rawSoundData.Clear();
     
                    if (this.WriteSoundToWaveFile(data.ToArray()))
                    {
                        return "ok";
                    }
                    else
                    {
                        return "Nook";
                    }
                }
                return "Nook";
            }
     
     
     
     
            //--- Enregistrement du son ---
            private bool WriteSoundToWaveFile(byte[] data)
            {
                int dataLength = data.Length;
                byte[] header = new byte[44];
     
                MemoryStream ms = new MemoryStream(header, 0, 44, true);
                UTF8Encoding utf8 = new UTF8Encoding();
     
                ms.Write(utf8.GetBytes("RIFF"), 0, 4);
                ms.Write(BitConverter.GetBytes(dataLength + 36), 0, 4);
                ms.Write(utf8.GetBytes("WAVE"), 0, 4);
                ms.Write(utf8.GetBytes("fmt "), 0, 4);
                ms.Write(BitConverter.GetBytes(16), 0, 4);
                ms.Write(BitConverter.GetBytes(1), 0, 2);
                ms.Write(BitConverter.GetBytes(this.waveFormat.Channels), 0, 2);
                ms.Write(BitConverter.GetBytes(this.waveFormat.SamplesPerSecond), 0, 4);
                ms.Write(BitConverter.GetBytes(this.waveFormat.AverageBytesPerSecond), 0, 4);
                ms.Write(BitConverter.GetBytes(this.waveFormat.BlockAlignment), 0, 2);
                ms.Write(BitConverter.GetBytes(this.waveFormat.BitsPerSample), 0, 2);
                ms.Write(utf8.GetBytes("data"), 0, 4);
                ms.Write(BitConverter.GetBytes(dataLength), 0, 4);
     
                try
                {
                    this.fileStream = new FileStream(this.fileName, FileMode.Create);
     
                    this.fileStream.Write(header, 0, header.Length);
     
                    this.fileStream.Write(data, 0, data.Length);
     
                    this.fileStream.Close();
                    this.fileStream.Dispose();
                    ms.Close();
                    ms.Dispose();
     
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
     
            }          
        }
    }

    Comme d'habitude, si quelqu'un à quoi que ce soit, le moindre petit conseil, c'est avec plaisir

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Points : 13
    Points
    13
    Par défaut
    Bon j'ai trouvé un article récent sur CodeProject qui à l'air d'être très très très très intéressant (quand on voit le b***el que c'est maintenant que DirectX est obsolète) pour facilement enregistrer du son et de la vidéo à partir d'une webcam en C#.

    J'ai pas encore tester, mais j'ai regarder le code et ça à l'air assez simple, les library utilisé sont celle de Microsoft Expression Encoder 4, donc logiquement, pas de mauvaise surprise...

    Peut-être la fin du cauchemard

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2011
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 27
    Points : 13
    Points
    13
    Par défaut
    Code testé et approuvé, ça marche nikel... Résolu!

    Pour ceux que ça intéresse :

    http://www.codeproject.com/KB/audio-...EE4WebCam.aspx

    Merci à tous ceux qui m'ont aidé

  10. #10
    Futur Membre du Club
    Inscrit en
    Juillet 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 20
    Points : 6
    Points
    6
    Par défaut
    Merci! je rencontrais le même problème.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Capture flux audio système
    Par mabsou dans le forum Langages de programmation
    Réponses: 0
    Dernier message: 13/07/2013, 23h03
  2. Capture du flux audio d'un device
    Par kertimanoff dans le forum C#
    Réponses: 4
    Dernier message: 28/09/2010, 13h56
  3. Capture flux video
    Par Albat90 dans le forum Dynamique
    Réponses: 1
    Dernier message: 12/01/2010, 16h34
  4. Redirection de flux audio/video
    Par wallain dans le forum C++
    Réponses: 0
    Dernier message: 26/08/2009, 11h02
  5. capture flux video impossible
    Par mystercedric dans le forum Firefox
    Réponses: 1
    Dernier message: 09/08/2009, 19h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo