Adobe flex 使用 Ogg Vorbis 编码器转换“.ogg”文件,以便用声音播放 class
Adobe flex convert ".ogg" file with Ogg Vorbis Encoder for being played with Sound class
我正在尝试从 URL 获取“.ogg”文件并在我的 Flex 程序中播放它。
我用“.mp3”文件进行了测试,一切正常,代码如下:
public function getFileRemote(url:String, id:String):void{
var s:Sound = new Sound();
s.addEventListener(Event.COMPLETE, onSoundLoaded);
var req:URLRequest = new URLRequest(url);
s.load(req);
}
private function onSoundLoaded(event:Event):void
{
var localSound:Sound = event.target as Sound;
localSound.play();
}
但是,对于“.ogg”格式的文件,它不起作用。因此,我已经检查了一些可能的解决方案,并且我正在尝试使用 Ogg Vorbis Encoder library 来实现一个。
我现在实现的代码:
public function getFileRemote(url:String, id:String):void
{
urlStream = new URLStream();
var urlReq:URLRequest = new URLRequest(url);
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load (urlReq);
}
private function handleSoundData(e:SampleDataEvent):void
{//handleSoundData
var result:Object;
var tmpBuffer:ByteArray = new ByteArray();
result = _oggManager.getSampleData(NUM_SAMPLES, tmpBuffer);
if (tmpBuffer.length < NUM_SAMPLES * BYTES_PER_SAMPLE)
{//reset
trace("Reset");
//Right now the only way to rewind is reseting the decoder
_oggManager.initDecoder(_oggBytes);
result = _oggManager.getSampleData( NUM_SAMPLES, tmpBuffer);
}//reset
tmpBuffer.position = 0;
while (tmpBuffer.bytesAvailable)
{//feed
//feed data
e.data.writeFloat(tmpBuffer.readFloat()); //Left Channel
e.data.writeFloat(tmpBuffer.readFloat()); //Right Channel
}//feed
}//handleSoundData
private function loaded(event:Event):void
{
urlStream.readBytes(_oggBytes, 0, urlStream.bytesAvailable);
//urlStream.readBytes(_oggBytes);
_oggManager.decode(_oggBytes);
//_oggManager.initDecoder(_oggBytes);
//Make sound
_sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, handleSoundData, false, 0, true);
_soundChannel = _sound.play();
//trace(urlLoader.data);
} */
在函数 loaded() 中,要么使用两种编码:
- _oggManager.decode(_oggBytes);
- _oggManager.initDecoder(_oggBytes);
我收到这个错误:
Main Thread (Suspended: TypeError: Error #1009: Cannot access a property or method of a null object reference.)
es.maubic.oxford.portal.views.sessions::ListAudiosView/loaded
那么,有什么建议吗?还有其他可能的解决方案吗?
更新
最后,我选择了另一种解决方案。
我拒绝将 ogg 音频转换为 mp3。
取而代之的是,现在 ogg 音频在服务器中,我只需要 URL 通过我的 MainApp.html 文件中的音频 html 标签播放它们。更简单,更高效。
我已经为问题中的问题找到了替代解决方案。
我没有将 .ogg 文件转换为 .mp3 文件,而是修改了我的代码以便直接在应用程序 .ogg 文件来自其 url(它存储在服务器中的位置)。
将此代码添加到主应用 html 文件(在我的例子中 Admin.html):
<audio id="audioOgg">
<source src='' type='audio/ogg'>
</audio>
<script language="JavaScript" type="text/javascript">
var media = document.getElementById("audioOgg");
var cp=document.getElementById("Admin");
var audioId;
function playAudio(audioURL, id) {
media.src = audioURL;
audioId = id;
media.play();
cp.onStartAudio(audioId);
}
function pauseAudio() {
media.pause();
}
</script>
并将此代码添加到 .mxml 文件中:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="Audio List"
horizontalScrollPolicy="off" verticalScrollPolicy="auto" width="510" height="340"
showCloseButton="true" close="closeWindow()">
<mx:Script>
<![CDATA[
import flash.external.ExternalInterface;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import mx.controls.Alert;
[Embed(source='../assets/play-btn-small.png')]
var Play:Class;
[Embed(source='../assets/stop-btn-small.png')]
var Stop:Class;
[Blindable]
public var dpc:ArrayCollection;
public function playAudio(audioURL:String, audioId:String){
ExternalInterface.call("playAudio", audioURL, id);
}
public function pauseAudio(){
ExternalInterface.call("pauseAudio");
}
]]>
</mx:Script>
<mx:Rotate id="rotate" />
<mx:Zoom id="zoom" />
<mx:VBox top="0" bottom="0" left="0" right="0" paddingTop="20" paddingLeft="20">
<mx:Text fontWeight="bold" height="20">
<mx:text>Click the play/pause button for listening/pause each audio individually:</mx:text>
</mx:Text>
</mx:VBox>
<mx:DataGrid id="gridAudios" top="50" bottom="20" left="20" right="20" width="100%" doubleClickEnabled="false">
<mx:columns>
<mx:DataGridColumn headerText="Name" dataField="audioId"/>
<mx:DataGridColumn id="btnCol" headerText="" textAlign="center">
<mx:itemRenderer>
<mx:Component>
<mx:HBox horizontalAlign="center">
<mx:Script>
<![CDATA[
protected function image1_clickHandler(event:MouseEvent):void
{
if (data.status=='playing'){
outerDocument.pauseAudio();
data.status='';
}else{
outerDocument.playAudio(data.url,data.audioId);
data.status='playing';
}
}
]]>
</mx:Script>
<mx:Image click="image1_clickHandler(event)"
toolTip="{data.status=='playing' ? 'Stop' : 'Play'}"
useHandCursor="true" source="{data.status=='playing' ? outerDocument.Stop : outerDocument.Play}"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:TitleWindow>
感谢 ExternalInterface class 我能够调用在我的文件中声明的 Javascript 函数Admin.html 文件以再现和停止标签元素的音频,将音频 url 和音频标识符作为参数传递。
我正在尝试从 URL 获取“.ogg”文件并在我的 Flex 程序中播放它。
我用“.mp3”文件进行了测试,一切正常,代码如下:
public function getFileRemote(url:String, id:String):void{
var s:Sound = new Sound();
s.addEventListener(Event.COMPLETE, onSoundLoaded);
var req:URLRequest = new URLRequest(url);
s.load(req);
}
private function onSoundLoaded(event:Event):void
{
var localSound:Sound = event.target as Sound;
localSound.play();
}
但是,对于“.ogg”格式的文件,它不起作用。因此,我已经检查了一些可能的解决方案,并且我正在尝试使用 Ogg Vorbis Encoder library 来实现一个。
我现在实现的代码:
public function getFileRemote(url:String, id:String):void
{
urlStream = new URLStream();
var urlReq:URLRequest = new URLRequest(url);
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load (urlReq);
}
private function handleSoundData(e:SampleDataEvent):void
{//handleSoundData
var result:Object;
var tmpBuffer:ByteArray = new ByteArray();
result = _oggManager.getSampleData(NUM_SAMPLES, tmpBuffer);
if (tmpBuffer.length < NUM_SAMPLES * BYTES_PER_SAMPLE)
{//reset
trace("Reset");
//Right now the only way to rewind is reseting the decoder
_oggManager.initDecoder(_oggBytes);
result = _oggManager.getSampleData( NUM_SAMPLES, tmpBuffer);
}//reset
tmpBuffer.position = 0;
while (tmpBuffer.bytesAvailable)
{//feed
//feed data
e.data.writeFloat(tmpBuffer.readFloat()); //Left Channel
e.data.writeFloat(tmpBuffer.readFloat()); //Right Channel
}//feed
}//handleSoundData
private function loaded(event:Event):void
{
urlStream.readBytes(_oggBytes, 0, urlStream.bytesAvailable);
//urlStream.readBytes(_oggBytes);
_oggManager.decode(_oggBytes);
//_oggManager.initDecoder(_oggBytes);
//Make sound
_sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, handleSoundData, false, 0, true);
_soundChannel = _sound.play();
//trace(urlLoader.data);
} */
在函数 loaded() 中,要么使用两种编码:
- _oggManager.decode(_oggBytes);
- _oggManager.initDecoder(_oggBytes);
我收到这个错误:
Main Thread (Suspended: TypeError: Error #1009: Cannot access a property or method of a null object reference.)
es.maubic.oxford.portal.views.sessions::ListAudiosView/loaded
那么,有什么建议吗?还有其他可能的解决方案吗?
更新
最后,我选择了另一种解决方案。 我拒绝将 ogg 音频转换为 mp3。 取而代之的是,现在 ogg 音频在服务器中,我只需要 URL 通过我的 MainApp.html 文件中的音频 html 标签播放它们。更简单,更高效。
我已经为问题中的问题找到了替代解决方案。
我没有将 .ogg 文件转换为 .mp3 文件,而是修改了我的代码以便直接在应用程序 .ogg 文件来自其 url(它存储在服务器中的位置)。
将此代码添加到主应用 html 文件(在我的例子中 Admin.html):
<audio id="audioOgg">
<source src='' type='audio/ogg'>
</audio>
<script language="JavaScript" type="text/javascript">
var media = document.getElementById("audioOgg");
var cp=document.getElementById("Admin");
var audioId;
function playAudio(audioURL, id) {
media.src = audioURL;
audioId = id;
media.play();
cp.onStartAudio(audioId);
}
function pauseAudio() {
media.pause();
}
</script>
并将此代码添加到 .mxml 文件中:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" title="Audio List"
horizontalScrollPolicy="off" verticalScrollPolicy="auto" width="510" height="340"
showCloseButton="true" close="closeWindow()">
<mx:Script>
<![CDATA[
import flash.external.ExternalInterface;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import mx.controls.Alert;
[Embed(source='../assets/play-btn-small.png')]
var Play:Class;
[Embed(source='../assets/stop-btn-small.png')]
var Stop:Class;
[Blindable]
public var dpc:ArrayCollection;
public function playAudio(audioURL:String, audioId:String){
ExternalInterface.call("playAudio", audioURL, id);
}
public function pauseAudio(){
ExternalInterface.call("pauseAudio");
}
]]>
</mx:Script>
<mx:Rotate id="rotate" />
<mx:Zoom id="zoom" />
<mx:VBox top="0" bottom="0" left="0" right="0" paddingTop="20" paddingLeft="20">
<mx:Text fontWeight="bold" height="20">
<mx:text>Click the play/pause button for listening/pause each audio individually:</mx:text>
</mx:Text>
</mx:VBox>
<mx:DataGrid id="gridAudios" top="50" bottom="20" left="20" right="20" width="100%" doubleClickEnabled="false">
<mx:columns>
<mx:DataGridColumn headerText="Name" dataField="audioId"/>
<mx:DataGridColumn id="btnCol" headerText="" textAlign="center">
<mx:itemRenderer>
<mx:Component>
<mx:HBox horizontalAlign="center">
<mx:Script>
<![CDATA[
protected function image1_clickHandler(event:MouseEvent):void
{
if (data.status=='playing'){
outerDocument.pauseAudio();
data.status='';
}else{
outerDocument.playAudio(data.url,data.audioId);
data.status='playing';
}
}
]]>
</mx:Script>
<mx:Image click="image1_clickHandler(event)"
toolTip="{data.status=='playing' ? 'Stop' : 'Play'}"
useHandCursor="true" source="{data.status=='playing' ? outerDocument.Stop : outerDocument.Play}"/>
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:TitleWindow>
感谢 ExternalInterface class 我能够调用在我的文件中声明的 Javascript 函数Admin.html 文件以再现和停止标签元素的音频,将音频 url 和音频标识符作为参数传递。