Hämta ljudindata

Flash Player 9 och senare, Adobe AIR 1.0 och senare

Med klassen Microphone kan programmet ansluta till en mikrofon eller annan ljudindataenhet i användarens system och sända indataljudet till högtalarna i det systemet eller skicka ljuddata till en fjärrserver, t.ex. Flash Media Server. Du kan komma åt de råa ljuddata från mikrofonen och spela in eller bearbeta dem. Du kan också skicka ljudet direkt till systemets högtalare eller skicka komprimerade ljuddata till en fjärrserver. Du kan använda Speex- eller Nellymoser-kodeken för data som skickas till en fjärrserver. (Speex-kodeken stöds från och med Flash Player 10 och Adobe AIR 1.5.)

Använda en mikrofon

Klassen Microphone har ingen konstruktormetod. I stället använder du den statiska Microphone.getMicrophone() -metoden för att hämta en ny Microphone-instans enligt nedan:

var mic:Microphone = Microphone.getMicrophone();

Om du anropar Microphone.getMicrophone() -metoden utan en parameter, returneras den första ljudindataenheten som påträffas i användarens system.

Ett system kan ha fler än en ljudindataenhet ansluten. Programmet kan använda egenskapen Microphone.names för att få en array med namnen på alla tillgängliga ljudindataenheter. Sedan kan det anropa Microphone.getMicrophone() -metoden med en index -parameter som matchar indexvärdet för enhetens namn i arrayen.

Ett system kanske inte har någon mikrofon eller andra indataenheter för ljud anslutna. Du kan använda egenskapen Microphone.names eller metoden Microphone.getMicrophone() för att kontrollera om användaren har någon ljudindataenhet installerad. Om användaren inte har installerat någon ljudindataenhet har names -arrayen längden noll och getMicrophone() -metoden returnerar värdet null .

När programmet anropar Microphone.getMicrophone() -metoden, visar Flash Player dialogrutan Flash Player-inställningar som uppmanar användaren att antingen tillåta eller neka Flash Player åtkomst till kameran och mikrofonen i systemet. När användaren har klickat på Tillåt eller Neka i dialogrutan skickas ett StatusEvent-objekt. Egenskapen code i StatusEvent-instansen anger om åtkomst till mikrofonen tilläts eller nekades enligt det här exemplet:

import flash.media.Microphone; 
 
var mic:Microphone = Microphone.getMicrophone(); 
mic.addEventListener(StatusEvent.STATUS, this.onMicStatus); 
 
function onMicStatus(event:StatusEvent):void 
{ 
    if (event.code == "Microphone.Unmuted") 
    { 
        trace("Microphone access was allowed."); 
    }  
    else if (event.code == "Microphone.Muted") 
    { 
         trace("Microphone access was denied."); 
    } 
}

StatusEvent.code -egenskapen innehåller ”Microphone.Unmuted” om åtkomst tilläts eller ”Microphone.Muted” om åtkomst nekades.

Egenskapen Microphone.muted anges till true respektive false när användaren tillåter eller nekar åtkomst till mikrofonen. Men egenskapen muted anges inte för Microphone-instansen förrän StatusEvent-händelsen har skickats, och därför bör programmet också vänta tills händelsen StatusEvent.STATUS skickas innan Microphone.muted -egenskapen kontrolleras.

För att Flash Player ska kunna visa dialogrutan med inställningar måste programfönstret vara tillräckligt stort (minst 215 x 138 pixlar). Annars nekas åtkomst automatiskt.

Innehåll som körs i AIR-programmets sandlåda behöver inte användarens tillåtelse för att komma åt mikrofonen. Därför skickas aldrig några statushändelser för ljud av och ljud på för mikrofonen. Innehåll som körs i AIR utanför programmets sandlåda behöver däremot användarens tillåtelse så dessa statushändelser kan skickas.

Dirigera mikrofonljud till lokala högtalare

Ljudindata från en mikrofon kan dirigeras till de lokala högtalarna genom anrop av Microphone.setLoopback() -metoden med parametervärdet true .

När ljud från en lokal mikrofon dirigeras till lokala högtalare finns det risk att rundgång skapas, vilket kan förorsaka högt och skrikigt ljud och kan leda till att ljudhårdvaran kan skadas. Genom att anropa metoden Microphone.setUseEchoSuppression() med parametervärdet true reduceras risken för rundgång, men den elimineras inte helt. Adobe rekommenderar att du alltid anropar Microphone.setUseEchoSuppression(true) före anropet av Microphone.setLoopback(true) såvida du inte är säker på att användarna spelar upp ljudet i hörlurar eller liknande, men inte i högtalare.

I följande kod visas hur ljud dirigeras från en lokal mikrofon till de lokala högtalarna:

var mic:Microphone = Microphone.getMicrophone(); 
mic.setUseEchoSuppression(true); 
mic.setLoopBack(true);

Ändra mikrofonljud

Programmet kan ändra ljuddata som kommer från en mikrofon på två sätt. Det kan ändra förstärkningen av indataljudet, vilket i praktiken innebär att indatavärden multipliceras med ett specificerat tal för att skapa ett högre eller lägre ljud. Egenskapen Microphone.gain accepterar numeriska värden från 0 t.o.m. 100. Värdet 50 fungerar som en multiplikator på ett och anger normal volym. Värdet noll fungerar som en multiplikator på noll och avbryter indataljudet. Värden över 50 anger högre volymer än normalt.

Programmet kan också ändra samplingsfrekvensen för indataljud. Högre samplingsfrekvenser ökar ljudkvaliteten men de skapar också tätare dataflöden som använder mer resurser för överföring och lagring. Egenskapen Microphone.rate representerar ljudets samplingsfrekvens mätt i kilohertz (kHz). Standardsamplingsfrekvensen är 8 kHz. Du kan ange ett högre värde än 8 kHz för Microphone.rate -egenskapen om mikrofonen klarar den högre frekvensen. Om du t.ex. anger värdet 11 för Microphone.rate -egenskapen, blir samplingsfrekvensen 11 kHz. Värdet 22 ger samplingsfrekvensen 22 kHz och så vidare. Vilka samplingsfrekvenser som finns beror på den valda koden. När du använder Nellymoser-koden kan du ange 5, 8, 11, 16, 22 och 44 kHz som samplingsfrekvens. När du använder Speex-kodeken (som är tillgänglig från och med Flash Player 10 och Adobe AIR 1.5) kan du bara använda 16 kHz.

Identifiera mikrofonaktivitet

För att spara bandbredd och bearbetningsresurser försöker Flash Player identifiera när inget ljud överförs via en mikrofon. När mikrofonens aktivitetsnivå stannar under tystnadsnivåtröskeln för en tidsperiod, slutar Flash Player att överföra ljudindata och skickar en enkel ActivityEvent i stället. När du använder Speex-kodeken (som är tillgänglig från och med Flash Player 10 eller senare och Adobe AIR 1.5 eller senare) ställer du in tystnadsnivån på 0 för att försäkra att ljudinformationen överförs kontinuerligt. Speex-röstidentifiering minskar bandbredden automatiskt.

Obs! Ett Microphone-objekt skickar bara aktivitetshändelser när programmet övervakar mikrofonen. Därför skickas inga aktivitetshändelser om du inte anropar setLoopBack( true ) , lägger till en lyssnare för samplingsdatahändelser eller kopplar mikrofonen till ett NetStream-objekt.

Tre egenskaper i klassen Microphone övervakar och styr identifieringen av aktivitet:

  • Den skrivskyddade activityLevel -egenskapen indikerar mängden ljud som mikrofonen identifierar på en skala från 0 till 100.

  • Med silenceLevel -egenskapen specificeras mängden ljud som behövs för att aktivera mikrofonen och skicka en ActivityEvent.ACTIVITY -händelse. Egenskapen silenceLevel använder också en skala från 0 till 100, och standardvärdet är 10.

  • Egenskapen silenceTimeout beskriver antal millisekunder som aktivitetsnivån måste vara under tystnadsnivån tills en ActivityEvent.ACTIVITY -händelse skickas för att indikera att mikrofonen nu är tyst. Standardvärdet för silenceTimeout är 2000.

Båda egenskaperna Microphone.silenceLevel och Microphone.silenceTimeout är skrivskyddade men deras värden kan ändras med Microphone.setSilenceLevel() -metoden.

I några fall kan proceduren för aktivering av mikrofonen förorsaka en kort fördröjning när ny aktivitet identifieras. Om mikrofonen alltid är aktiverad kan sådan aktiveringsfördröjning tas bort. Programmet kan anropa Microphone.setSilenceLevel() -metoden med värdet noll i silenceLevel -parametern som indikerar för Flash Player att hålla mikrofonen aktiv och fortsätta samla ljuddata även om inget ljud identifieras. Omvänt förhindras mikrofonen från att aktiveras om värdet 100 anges i silenceLevel -parametern.

Följande exempel visar information om mikrofonen och rapporterar om aktivitets- och statushändelser som skickas av ett Microphone-objekt:

import flash.events.ActivityEvent; 
import flash.events.StatusEvent; 
import flash.media.Microphone; 
 
var deviceArray:Array = Microphone.names; 
trace("Available sound input devices:"); 
for (var i:int = 0; i < deviceArray.length; i++) 
{ 
    trace(" " + deviceArray[i]); 
} 
 
var mic:Microphone = Microphone.getMicrophone(); 
mic.gain = 60; 
mic.rate = 11; 
mic.setUseEchoSuppression(true); 
mic.setLoopBack(true); 
mic.setSilenceLevel(5, 1000); 
     
mic.addEventListener(ActivityEvent.ACTIVITY, this.onMicActivity); 
mic.addEventListener(StatusEvent.STATUS, this.onMicStatus); 
     
var micDetails:String = "Sound input device name: " + mic.name + '\n'; 
micDetails += "Gain: " + mic.gain + '\n'; 
micDetails += "Rate: " + mic.rate + " kHz" + '\n'; 
micDetails += "Muted: " + mic.muted + '\n'; 
micDetails += "Silence level: " + mic.silenceLevel + '\n'; 
micDetails += "Silence timeout: " + mic.silenceTimeout + '\n'; 
micDetails += "Echo suppression: " + mic.useEchoSuppression + '\n'; 
trace(micDetails); 
 
function onMicActivity(event:ActivityEvent):void 
{ 
    trace("activating=" + event.activating + ", activityLevel=" +  
        mic.activityLevel); 
} 
 
function onMicStatus(event:StatusEvent):void 
{ 
    trace("status: level=" + event.level + ", code=" + event.code); 
}

När du kör exemplet ovan, pratar eller testar ljud i systemmikrofonen och tittar på de resulterande trace-programsatserna som visas på en konsol eller i ett felsökningsfönster.

Skicka ljud till och från en medieserver

Ytterligare ljudmöjligheter finns tillgängliga när ActionScript används med direktuppspelning med en mediaserver som Flash Media Server (FMS).

Särskilt kan programmet bifoga ett Microphone-objekt till ett NetStream-objekt och överföra data direkt från användarens mikrofon till servern. Ljuddata kan också direktuppspelas från servern till ett program och spelas upp som en del av ett MovieClip-objekt eller via ett Video-objekt.

Speex-kodeken är tillgänglig från och med Flash Player 10 och Adobe AIR 1.5. Om du vill ställa in kodeken som används för komprimerat ljud som skickas till medieservern ställer du in codec -egenskapen för Microphone-objektet. Den här egenskapen kan ha två värden, som räknas upp i klassen SoundCodec. Om du ställer in kodegenskapen på SoundCodec.SPEEX väljs Speex-kod för ljudkomprimering. Om du ställer in egenskapen på SoundCodec.NELLYMOSER (standardvärde) väljs Nellymoser-koden för ljudkomprimering.

Mer information finns i dokumentationen till Flash Media Server på www.adobe.com/go/learn_fms_docs_se .

Hämta mikrofonljuddata

I Flash Player 10.1 och AIR 2 (eller senare versioner) kan du hämta data från en mikrofon som en bytearray med flyttalsvärden. Varje värde motsvarar en sampling med monofoniska ljuddata.

Om du vill hämta mikrofondata anger du en händelseavlyssnare för händelsen sampleData i Microphone-objektet. Microphone-objektet skickar sampleData -händelser med jämna mellanrum när mikrofonbufferten fylls med ljudsamplingar. SampleDataEvent-objektet har en data -egenskap som är en bytearray med ljud samplingar. Alla samplingar representeras som flyttalsvärden, och alla värden motsvarar en monofonisk ljudsampling.

Följande kod hämtar mikrofonljuddata till ett ByteArray-objekt med namnet soundBytes :

var mic:Microphone = Microphone.getMicrophone(); 
mic.setSilenceLevel(0, DELAY_LENGTH); 
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler); 
function micSampleDataHandler(event:SampleDataEvent):void { 
    while(event.data.bytesAvailable)     { 
        var sample:Number = event.data.readFloat(); 
        soundBytes.writeFloat(sample); 
    } 
}

Du kan återanvända samplingsbyte som uppspelningsljud för ett Sound-objekt. Om du gör det ska du ange egenskapen rate för Microphone-objektet till 44, vilket är den samplingsfrekvens som används av Sound-objekt. (Du kan också konvertera mikrofonsamplingar som hämtats med en lägre frekvens till frekvensen 44 kHz, som krävs för Sound-objektet.) Tänk också på att Microphone-objektet hämtar monofoniska samplingar, men att Sound-objektet använder stereoljud. Därför får du skriva de byte som hämtats av Microphone-objektet till Sound-objektet två gånger. I följande exempel hämtas 4 sekunder med mikrofondata och spelas sedan upp med hjälp av ett Sound-objekt:

const DELAY_LENGTH:int = 4000; 
var mic:Microphone = Microphone.getMicrophone(); 
mic.setSilenceLevel(0, DELAY_LENGTH); 
mic.gain = 100; 
mic.rate = 44; 
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler); 
 
var timer:Timer = new Timer(DELAY_LENGTH); 
timer.addEventListener(TimerEvent.TIMER, timerHandler); 
timer.start(); 
 
function micSampleDataHandler(event:SampleDataEvent):void 
{ 
    while(event.data.bytesAvailable) 
    { 
        var sample:Number = event.data.readFloat(); 
        soundBytes.writeFloat(sample); 
    } 
} 
var sound:Sound = new Sound(); 
var channel:SoundChannel; 
function timerHandler(event:TimerEvent):void 
{ 
    mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler); 
    timer.stop(); 
    soundBytes.position = 0; 
    sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler); 
    channel.addEventListener( Event.SOUND_COMPLETE, playbackComplete ); 
    channel = sound.play(); 
} 
 
function playbackSampleHandler(event:SampleDataEvent):void 
{ 
    for (var i:int = 0; i < 8192 && soundBytes.bytesAvailable > 0; i++) 
    { 
        trace(sample); 
        var sample:Number = soundBytes.readFloat(); 
        event.data.writeFloat(sample); 
        event.data.writeFloat(sample); 
    } 
} 
 
function playbackComplete( event:Event ):void 
{ 
    trace( "Playback finished."); 
}

Mer information om att spela upp ljud från ljudsamplingsdata finns i Arbeta med dynamiskt skapat ljud .