Placeholder-Software / Dissonance

Unity Voice Chat Asset
70 stars 5 forks source link

How to record room chat all players voice? #116

Closed fingerx closed 5 years ago

fingerx commented 5 years ago

using last dissonance plugin to my unity destktop app. I want to record all player voice. eg: player a enter room , player a ,player b,player c are talking in the same room. when player a press button start recording all voice. press other button stop record. can you tell me how can do that. if show me code I may understand better. thank very much.

martindevans commented 5 years ago

Unfortunately Dissonance doesn't have a built in way to do exactly what you want.

The easiest way to do it will be to add a component to the playback prefab using OnAudioFilterRead to capture the audio (make sure your filter comes after the Dissonance SamplePlaybackComponent). This will give you the audio stream for each player separately, you'd then have to mix them together before writing to file.

Dissonance doesn't handle mixing the audio so if you want to get the mixed audio you'll need to work out a way to record the Unity Audio Mixer which you are sending all the Dissonance voices to.

fingerx commented 5 years ago

thanks martindevans.I probably understand but find OnAudioFilterRead method how to convert voice packet to wav file and save. cant find doc about this. can you show code for me?thanks.

martindevans commented 5 years ago

Dissonance actually has an internal class for this (we use it for debugging). Have a look at Assets/Plugins/Dissonance/Core/Audio/AudioFileWriter.cs

fingerx commented 5 years ago

@martindevans look at AudioFileWriter.cs i understand how to save wav file to my disk but record all player voice is hard to me. so i change my idea to record my local player voice. I find BasicMicrophoneCapture file. write test script "MyMicrophpneCapture" but show error: "DissonanceException: Error: Attempted to Start microphone capture, but capture is already running! This is probably a bug in Dissonance, we're sorry! Please report the bug on the issue tracker..."

this my code:

MyMicrophpneCapture.txt

fingerx commented 5 years ago

@martindevans this my fault. i change my code:

using Dissonance;
using UnityEngine;

public class MyMicrophpneCapture : MonoBehaviour
{   
    DissonanceComms comms;
    MyMicrophoneSubscriber listener;
    void Start()
    {
        comms = gameObject.GetComponent<DissonanceComms>();
        listener = gameObject.GetComponent<MyMicrophoneSubscriber>();
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            comms.MicrophoneCapture.Subscribe(listener);
        }

        if (Input.GetKeyDown(KeyCode.M))
        {
            comms.MicrophoneCapture.Unsubscribe(listener);
        }
    }

}

//==========================

public class MyMicrophoneSubscriber : MonoBehaviour, IMicrophoneSubscriber
{       
    public void ReceiveMicrophoneData(ArraySegment<float> buffer, WaveFormat format)
    {   
        //how convter buffer to wav file ?
    }

    public void Reset()
    {
        //do what?
    }

}

but i dont how to write Reset and ReceiveMicrophoneData,can you show code for me. thanks very much.

martindevans commented 5 years ago

You don't need to modify the microphone capture script to do this, there are two better ways to do it.


Firstly Dissonance does have a way built in to record the microphone - we use it for debugging. Check out Window > Dissonance > Diagnostic Settings, you can enable Recording Diagnostics > Record Preprocessor Output which will write all audio from the preprocessor to disk (even when the user isn't broadcasting their mic is running). This isn't really intended for end users - there's a chance it could stall the preprocessor if I/O is too slow, but it's a good start.


The second way requires a slight modification to Dissonance. We have a system for "subscribing" to events. Have a look at DissonanceComms.cs Line 610 and you'll see how this works for subscribing to voice activation events. The same API exists for subscribing to receive raw microphone data, but it's not publicly exposed. I would suggest duplicating the VAD API but with the IMicrophoneSubscriber type. You'll need to add:

Duplicating the logic of SubcribeToVoiceActivation and UnsubscribeFromVoiceActivation in DissonanceComms:

Duplicating the logic of Subscribe and Unsubscribe in CapturePipelineManager:

And that should be it. Now you can write an implementation of IMicrophoneSubscriber which records audio. You can subscribe and unsubscribe the recorder only when the local player is broadcasting (use DissonanceComms:FindPlayer(DissonanceComms:LocalPlayerName) to get a player object, there are events on here for joining and leaving channels).

fingerx commented 5 years ago

thanks, using second way succes save local player voice. @martindevans thanks again