2012-01-04 2 views
2

이것은 나의 첫 번째 질문이다 : D, 나의 영어에 대해 처음으로 유감스럽게 생각한다.어떻게 MovieClip (비트 맵 및 오디오)을 FLV에 저장할 수 있습니까?

내 질문은 기본적으로 플래시 무비 클립을 FLV로 저장하는 방법입니다.

무비 클립은 사용자가 생성하며 다양한 사운드와 애니메이션을 가지고 있으며 FLV를 저장하여 Youtbue로 보내야합니다.

무엇을 시도해 보셨습니까 : Movie Clip 프레임을 프레임에 집어 Bitmap에 저장하는 데 사용하는 Alchemy Lib 사용에 관한 질문이 있습니다.

Alchemy Lib은 이러한 프레임을 매력처럼 FLV로 변환하고 ByteArray를 사용하여 사운드 청크 저장을 지원합니다.

내 문제는 어떻게 영화 클립을 Alchemy Lib에 보낼 수 있습니까?

SoundMixer.computeSpectrum(sndData, false, 2); 

마녀가 나에게 sndData 변수에 BYTEARRAY을 반환하지만 사용 키우면 화면에 오디오 웨이브 폼을 렌더링하기 때문에 쓸모가 : I've 사용하여 시도했다.

Thougth

Sound.extract(); 

를 사용 aboud하지만 난 사운드 클래스는 하나의 MP3 사운드에 사용됩니다 믿고 나는 무비 클립에 의해 생성 된 혼합 소리를 잡아해야합니다.

MovieClip에서 FLV를 생성하는 또 다른 방법이 있습니까? 내 코드의 일부 아래

:

은 내가이 링크에있는 튜토리얼에서 내 코드를 기반 : 그것을 http://www.zeropointnine.com/blog/updated-flv-encoder-alchem/

private const OUTPUT_WIDTH:Number = 550; 
private const OUTPUT_HEIGHT:Number = 400; 
private const FLV_FRAMERATE:int = 24; 
private var _baFlvEncoder:ByteArrayFlvEncoder;  
public var anime:MovieClip; 


//Starts recording 
public function startRecording() 
{ 
    this.addEventListener(Event.ENTER_FRAME, enterFrame); 

    //Initialize the Alchemy Lib 
    _baFlvEncoder = new ByteArrayFlvEncoder(stage.frameRate); 
    _baFlvEncoder.setVideoProperties(OUTPUT_WIDTH, OUTPUT_HEIGHT); 
    _baFlvEncoder.setAudioProperties(FlvEncoder.SAMPLERATE_22KHZ); 
    _baFlvEncoder.start();  

} 
//Stops recording 
public function stopRecording() 
{ 
    this.removeEventListener(Event.ENTER_FRAME, enterFrame); 
    _baFlvEncoder.updateDurationMetadata(); 

    // Save FLV file via FileReference 
    var fileRef:FileReference = new FileReference(); 
    fileRef.save(_baFlvEncoder.byteArray, "test.flv");   

    _baFlvEncoder.kill(); 

} 

//The Main Loop activated by StartRecording 
public function enterFrame(evt:Event) 
{ 
    var bmpData:BitmapData = new BitmapData(OUTPUT_WIDTH, OUTPUT_HEIGHT, false, 0xFFFFFFFF); 
    bmpData.draw(anime); 

    var sndData:ByteArray = new ByteArray(); 
    SoundMixer.computeSpectrum(sndData, false, 2); 

    _baFlvEncoder.addFrame(bmpData, sndData); 
    bmpData.dispose(); 


} 
+0

왜 FLV가 특별히 필요합니까? 플래시 IDE를 사용하고 있습니까? 그렇다면 동영상을 AVI (파일 | 내보내기 | "동영상 내보내기 ...")로 내보내고 그런 방식으로 YouTube에 업로드 할 수 있습니다. – iND

+0

MovieClip에는 soundTransform 속성 만 있지만 사운드 객체에 대한 액세스 권한이 없기 때문에 현재로서는 그럴 가능성이 없습니다. Adobe 의도적으로 어쩌면이 기능을 추가하지 않아서 AS3에서 swf2flv 자체 수출 업체를 만들 수 없습니다. –

+0

나는 힘든 방법을하는 방법을 알고있다 : 사운드 데이터가 MovieClip 객체와 함께 저장되어있을 수 있으므로 바이트 배열로 직렬화 한 다음 사운드 데이터를 찾고 추출하기 위해 바이트 코드를 추출하려고 할 수있다. :) –

답변

1

을 완료! (음 ... 거의 : D)

내 문제는 MovieClip의 오디오 뿐이므로 복잡했기 때문에 믹서처럼 작동하는 클래스를 만들었습니다.

믹서는 모든 사운드의 바이트를 혼합하는 고유 한 SampleDataEvent를 사용하여 모든 사운드를 재생해야합니다. 또한 startRecording 함수를 실행할 때 ByteArray에 단일 사운드 데이터를 생성합니다.

/**** MySoundMixer initializations omitted ***/ 

//Generates the sound object to start the stream 
//for reproduce the mixed sounds. 
public function startStream() 
{ 
    fullStreamSound= new Sound(); 
    fullStreamSoundData = new ByteArray();    
    this.fullStreamSoundChannel = this.fullStreamSound.play(); 
} 

//Adds a sound in the soundlib 
//(See: MySound object for more details) 
public function addSound(sound:MySound, key:String) 
{ 
    sound.initialize(); 
    sounds.push({sound:sound, key:key}); 
} 

//Play a sound in the sound lib 
public function play(key) 
{ 
    var founded:MySound = null; 
    for (var i = 0; i < sounds.length; i++) 
    { 
     if (key == sounds[i].key) 
     { 
      founded = sounds[i].sound; 
      break; 
     } 
    } 
    if (founded != null) 
    { 
     founded.play(); 
    } 
} 

// The SampleDataEvent function to Play the sound and 
// if recording is activated record the sound to fullStreamSoundData 
public function processSampleData(event:SampleDataEvent) 
{ 
    var pos = 0; 

    var normValue:Number = 1/this.sounds.length; 
    while (pos < BUFFER) 
    { 

     var leftChannel:Number = 0; 
     var rightChannel:Number = 0; 

     for (var i = 0; i < this.sounds.length; i++) 
     { 
      var currentSound:MySound = this.sounds[i].sound; 
      var result = currentSound.getSampleData(); 
      leftChannel += result.leftChannel * normValue; 
      rightChannel += result.rightChannel * normValue; 
     } 

     event.data.writeFloat(leftChannel); 
     event.data.writeFloat(rightChannel); 

     if (isRecording) 
     { 
      fullStreamSoundData.writeFloat(leftChannel); 
      fullStreamSoundData.writeFloat(rightChannel); 
     } 

     pos++; 
    } 
} 

//Starts recording 
public function startRecording() 
{ 
    this.isRecording = true; 
} 

//Stops recording 
public function stopRecording() 
{ 
    this.isRecording = false; 
} 

SampleDataEvent 놀이에 사용하고 동시에 혼합 된 사운드를 추출한다 : 종류 믹서에 대한 코드는 여기에 설명하기 복잡하지만.

는 또한 processSampleData 방법에 의해 사용되는 현재의 버퍼에 각각 음의 샘플 데이터 (방법 getSampleData())를 추출하기 위해 사운드 객체를 연장 MySound 클래스를 작성했다. MySound 클래스는 Mixer가 시작될 때 (두 채널 모두 0 바이트를 전송할 때) 재생을 시작하고 믹서가 멈 추면 멈추게되며 play() 함수가 호출 될 때만 음악의 바이트 정보를 보내기 시작합니다.I 믹서의 구멍 사운드 정보를 포함하는 고유 ByteArray 객체를 생성 한, 그와

/**** MySound initializations omitted ***/ 
public function initialize() 
{ 
    this.extractInformation(null); 
} 

//Override the play function to avoid playing. 
//(The play act will be triggered by SoundMixer class) 
override public function play(startTime:Number = 0, loops:int = 0, sndTransform:SoundTransform = null):SoundChannel 
{ 
    this.isPlaying = true; 
    this.currentPhase = 0; 
    return null; 
} 

// On each buffer in sampledata i read the chunk of sound bytes 
public function getSampleData() 
{ 
    var leftChannel:Number = 0; 
    var rightChannel:Number = 0; 
    if (this.isPlaying) { 
     if (currentPhase < totalPhases) 
     { 
      this.soundData.position = currentPhase * 8; 
      leftChannel = this.soundData.readFloat(); 
      rightChannel = this.soundData.readFloat(); 
      this.currentPhase ++; 
     } else 
     { 
      stopPlaying(); 
     } 
    } 
    return { leftChannel:leftChannel, rightChannel:rightChannel }; 
} 

//Extracts information of the sound object in order to 
//split it in several chunks of sounds. 
public function extractInformation(evt:Event) 
{ 
    trace("Inicializando o som " + this.id3); 
    this.soundData = new ByteArray(); 
    this.extract(soundData, int(this.length * SAMPLE_44HZ + 10000)); 
    this.totalPhases = this.soundData.length/8; 
    this.currentPhase = 0; 
} 

///Stop playing means stop extracting bytes 
public function stopPlaying() 
{ 
    this.isPlaying = false; 
} 

: 제가

작성한

클래스는 다음과 같이된다. movieclip이 시작될 때 믹서를 시작하고 무비 클립이 멈출 때도 멈추게해야합니다. 사운드 객체가있는 ByteArray 정보는 성공적으로 기록되는 Alchemy Lib의 addFrame (bitmapData, sndData)을 전달합니다.

내 프로젝트에서는 잘 작동하지만 코드를 최적화해야 할 수도 있습니다.

나를 도왔던 모든 사람들에게 감사드립니다!