WOWZA到IOS-如何直播流

WOWZA到IOS-如何直播流,ios,wowza,Ios,Wowza,到目前为止,我几乎为IOS开发了一款Flash Air应用程序,完成了50%。我使用RED5媒体服务器获得了所有的实时流媒体,但当我发现iPhone摄像头显示90度时,我就陷入了死胡同,因此发送并保存到RED5服务器的流也被记录为90度。我在网上读了很多关于堆栈溢出的文章,说这是一个已知的Bug。不确定何时会修复此问题。我还尝试了一些可以在我的Air应用程序中实现相机旋转的ANE Air原生扩展,这些是DiaDraw和StarlingCamera ANE,但在网上找不到任何信息教程,因此无法实现

到目前为止,我几乎为IOS开发了一款Flash Air应用程序,完成了50%。我使用RED5媒体服务器获得了所有的实时流媒体,但当我发现iPhone摄像头显示90度时,我就陷入了死胡同,因此发送并保存到RED5服务器的流也被记录为90度。我在网上读了很多关于堆栈溢出的文章,说这是一个已知的Bug。不确定何时会修复此问题。我还尝试了一些可以在我的Air应用程序中实现相机旋转的ANE Air原生扩展,这些是DiaDraw和StarlingCamera ANE,但在网上找不到任何信息教程,因此无法实现

Flash Adobe Air for IOS代码,连接到RED5服务器并显示iPhone摄像头为90度:

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.ActivityEvent;
import flash.events.MouseEvent;
import flash.media.Camera;
import flash.media.Video;
import flash.events.NetStatusEvent;
import flash.net.NetStream;
import flash.net.NetConnection;

 var nc:NetConnection;
 var cam:Camera;
 var vid:Video;
 var nsOut:NetStream;
 var nsIn:NetStream;




        // support autoOrients
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
        cam = Camera.getCamera();
        cam.setMode(320, 300, 25); 
        cam.setQuality(0,100);
        if (!cam) 
        {
            txt.text ="No camera is installed.";
        }
        else 
        {

            nc = new NetConnection(); 
            nc.connect("rtmp://192.168.1.5/RED5Hugt");
            nc.addEventListener(NetStatusEvent.NET_STATUS,getStream);     
            nc.client = this;


            //connectCamera();
        }

    function getStream(e:NetStatusEvent):void
    {

        connectCamera();
        nsIn = new NetStream(nc); 
        nsOut = new NetStream(nc); 

        vid.attachNetStream(nsIn);
        nsIn.play("tester");

         nsOut=new NetStream(nc);
         netOut.attachAudio(mic);
         nsOut.attachCamera(cam);
         nsOut.publish("tester", "live");


    // add click event to record button
    // add event for stage video render state
    }

     function connectCamera():void 
    {
        vid             = new Video();
        vid.width       = cam.width;
        vid.height      = cam.height; 
        vid.x = 0;
        vid.y = 0;
        vid.attachCamera(cam);
        addChild(vid);    

        //stage.addEventListener(MouseEvent.CLICK, clickHandler);
    }

     function clickHandler(e:MouseEvent):void 
    {

        return;

        switch (cam.width) {
            case 160:
                cam.setMode(320, 240, 10); 
                break;
            case 320:
                cam.setMode(640, 480, 5); 
                break;
            default:
                cam.setMode(160, 120, 15); 
                break;
        } 
        removeChild(vid);           
        connectCamera();
    }
RED5服务器代码:

package com;



import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;

import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IClient;
import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
import org.red5.server.api.scope.IScope;
import org.red5.server.api.service.IPendingServiceCall;
import org.red5.server.api.service.IPendingServiceCallback;
import org.red5.server.api.service.IServiceCapableConnection;
import org.red5.server.api.service.IServiceHandlerProvider;
import org.red5.server.api.stream.IBroadcastStream;
import org.red5.server.api.stream.IServerStream;
import org.red5.server.api.stream.support.SimplePlayItem;
import org.red5.server.api.stream.support.StreamUtils;
import org.red5.server.stream.ClientBroadcastStream;
import org.red5.server.stream.RecordingListener;

import static java.lang.System.*;


public class Application extends  MultiThreadedApplicationAdapter{
//private static final Log log = LogFactory.getLog( Application.class );
private IBroadcastStream serverStream;


@Override
public boolean appStart(IScope scope)
{
    if(!super.appStart(scope))
    {
        return false;
    }
    else
    {
        super.appStart(scope);
        return true;
    }
}

@Override
public void appStop(IScope scope)
{

}

//User connecting/disconnecting to/from application
@Override
public boolean appConnect(IConnection connection, Object[] parameters) {

    super.appConnect(connection, parameters);
    //connection.getClient().setAttribute("userName", parameters[0]);
    return true;
}

@Override
public void appDisconnect(IConnection connection) {
    super.appDisconnect(connection);
}


//User joining/leaving scope
@Override
public boolean appJoin(IClient client, IScope scope) 
{
    super.appJoin(client, scope);
    return true;
}

@Override
public void appLeave(IClient client, IScope scope)
{
    super.appLeave(client,scope);
}


public boolean connect(IConnection conn, IScope scope, Object[] params) {

    super.connect(conn, scope, params);

    return true;
}


}
于是我决定以本机方式进行流式传输,我使用objective-c中的媒体和CommLib库找到了这段代码,我将其粘贴到了Pastebin上,因为粘贴到这里时有太多的代码需要编辑:

这是成功连接到另一台PC上运行的RED5 Java应用程序适配器的RTMP客户端

当使用Xcode运行RTMP客户端时,应用程序正在进行流媒体直播,但每隔几秒钟音频就会出现故障,我无法找到任何可以解决此问题的方法,可能我需要更改一些代码,但我在线找到了此RTMP客户端代码,并修改了流名称和RTMP Url,以指向我在RED5服务器上的应用程序

为什么音频一直有问题。所以现在我想试试WOWZA媒体服务器

到目前为止,我下载了Wowza媒体服务器,然后安装了Eclipse。安装Eclipse之后,我安装了Wowza IDE,我在Eclipse中安装了该IDE,但请确保在安装Wowza IDE之前先安装Wowza媒体服务器

然后我在网上找到了一些代码,可能是在Wowza服务器上运行的服务器,新的Wowza服务器是在浏览器中运行的,我尝试在终端上运行此代码,但无法运行,因为它在终端上一直说“操作无法运行”

这是我用于服务器的代码:

package com;

import com.wowza.wms.application.*;
import com.wowza.wms.amf.*;
import com.wowza.wms.client.*;
import com.wowza.wms.module.*;
import com.wowza.wms.request.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.rtp.model.*;
import com.wowza.wms.httpstreamer.model.*;
import com.wowza.wms.httpstreamer.cupertinostreaming.httpstreamer.*;
import com.wowza.wms.httpstreamer.smoothstreaming.httpstreamer.*;

public class RED5Hugt extends ModuleBase {

public void doSomething(IClient client, RequestFunction function,
        AMFDataList params) {
    getLogger().info("doSomething");
    sendResult(client, params, "Hello Wowza");
}

public void onAppStart(IApplicationInstance appInstance) {
    String fullname = appInstance.getApplication().getName() + "/"
            + appInstance.getName();
    getLogger().info("onAppStart: " + fullname);
}

public void onAppStop(IApplicationInstance appInstance) {
    String fullname = appInstance.getApplication().getName() + "/"
            + appInstance.getName();
    getLogger().info("onAppStop: " + fullname);
}

public void onConnect(IClient client, RequestFunction function,
        AMFDataList params) {
    getLogger().info("onConnect: " + client.getClientId());
}

public void onConnectAccept(IClient client) {
    getLogger().info("onConnectAccept: " + client.getClientId());
}

public void onConnectReject(IClient client) {
    getLogger().info("onConnectReject: " + client.getClientId());
}

public void onDisconnect(IClient client) {
    getLogger().info("onDisconnect: " + client.getClientId());
}

public void onStreamCreate(IMediaStream stream) {
    getLogger().info("onStreamCreate: " + stream.getSrc());
}

public void onStreamDestroy(IMediaStream stream) {
    getLogger().info("onStreamDestroy: " + stream.getSrc());
}

}
所以现在我运行Xcode项目RTMP客户机,发现RTMP客户机确实连接了,但没有实时流。我只是想问我需要在哪里修改代码才能让流媒体直播正常工作

另外,根据我使用AdobeAIR for IOS和使用RED5的经验,我是否应该选择这最后一条路线,因为我不确定。我做了很多研究,我真的很想找到一种免费的方式来了解如何从IPhone摄像头中播放流媒体。我试过AdobeForiOS到RED5服务器,发现有一个已知的Bug,我试过RED5的原生版本,发现了音频故障,那么Wowza是最好的选择吗

更新 我在Xcode控制台中得到一个无法找到流的输出,以下是输出:

2014-07-30 13:33:06.246 RTMPStreamComeback[340:4003]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = MediaStreamPlayer, 4 = NetStream.Play.StreamNotFound
但是,就像RED5一样,音频似乎出现了故障,但除了音频,流从未中断

我怎样才能解决这个问题

这是来自Xcode的跟踪:

                   2014-07-30 15:19:48.296 RTMPStreamComeback[397:60b] connectControl: host = rtmp://192.168.1.4:1935/RED5Hugt
2014-07-30 15:19:49.325 RTMPStreamComeback[397:60b] Video encoding is initialized: bit_rate = 272000, rc_max_rate = 0, rc_min_rate = 0, qmin=2, qmax=31, qcompress=0.500000
2014-07-30 15:19:49.334 RTMPStreamComeback[397:60b] AudioCodec: codecID = 86050, codecType = 42, bitRate = 16000, _sampleBytes = 4
encoder supports the sample formats:
flt, 
audio codec best options: sample_rate = 44100
2014-07-30 15:19:49.340 RTMPStreamComeback[397:60b] audio codec context: codec_type = 1, sample_fmt = flt, bit_rate = 16000, sample_rate = 16000, channels = 1, frame_bits = 4, channel_layout = 0, frame_size = 0, buffer_size = 256
2014-07-30 15:19:49.344 RTMPStreamComeback[397:60b] initVideoCapture -> preset AVCaptureSessionPresetLow is supported, orientation = 3
2014-07-30 15:19:49.414 RTMPStreamComeback[397:60b] BroadcastStreamClient STREAM ----> name: tester, type: 2, [socket retainCount] = 3
2014-07-30 15:19:49.789 RTMPStreamComeback[397:60b]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = BroadcastStreamClient, 1 = RTMP.Client.isConnected
2014-07-30 15:19:49.831 RTMPStreamComeback[397:3f03]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = BroadcastStreamClient, 2 = RTMP.Client.Stream.isCreated
2014-07-30 15:19:50.585 RTMPStreamComeback[397:3f03]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = BroadcastStreamClient, 3 = NetStream.Publish.Start
[flv @ 0x1883d000] Error, Invalid timestamp=0, last=0
[flv @ 0x1883d000] Error, Invalid timestamp=0, last=0
[flv @ 0x1883d000] Error, Invalid timestamp=0, last=0
2014-07-30 15:20:01.677 RTMPStreamComeback[397:60b] publishControl: stream = slavav
2014-07-30 15:20:01.680 RTMPStreamComeback[397:60b] NellyMoserDecoder -> audio codec context: codec_type = 1, sample_fmt = flt, bit_rate = 16000, sample_rate = 16000, channels = 1, frame_bits = 4, channel_layout = 0, frame_size = 0
2014-07-30 15:20:01.681 RTMPStreamComeback[397:60b] Set Player's Framework -> 'AudioUnit'
2014-07-30 15:20:01.685 RTMPStreamComeback[397:60b] VideoStream decoding is initialized: context->pix_fmt = 0, width = 0, height = 0
2014-07-30 15:20:01.689 RTMPStreamComeback[397:60b]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = MediaStreamPlayer, 1 = RTMP.Client.isConnected
2014-07-30 15:20:01.712 RTMPStreamComeback[397:3f03]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = MediaStreamPlayer, 2 = RTMP.Client.Stream.isCreated
2014-07-30 15:20:01.758 RTMPStreamComeback[397:3f03]  $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = MediaStreamPlayer, 3 = NetStream.Play.Start
[flv @ 0x1808c600] Bad picture start code
[flv @ 0x1808c600] header damaged
2014-07-30 15:20:01.764 RTMPStreamComeback[397:3f03] VideoStream -> decodeFrame: (ERROR) got_packet = 0, processed_size = -1
[swscaler @ 0x2e38000] No accelerated colorspace conversion found from yuv420p to bgra.
2014-07-30 15:20:01.775 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -> nextFrame: < NO PCM - WHITE NOISE > timestamp = 11192, dropWhiteNoise = 0
2014-07-30 15:20:01.799 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -> nextFrame: < NO PCM - WHITE NOISE > timestamp = 11215, dropWhiteNoise = 0
 2014-07-30 15:20:01.821 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -> nextFrame: < NO PCM - WHITE NOISE > timestamp = 11238, dropWhiteNoise = 0
 2014-07-30 15:20:01.845 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -> nextFrame: < NO PCM - WHITE NOISE > timestamp = 11261, dropWhiteNoise = 0
  2014-07-30 15:20:01.867 RTMPStreamComeback[397:7a03] MPAudioUnitEngine -> nextFrame: < NO PCM - WHITE NOISE > timestamp = 11284, dropWhiteNoise = 0
[flv @ 0x1808c600] Bad picture start code
[flv @ 0x1808c600] header damaged
  2014-07-30 15:20:01.888 RTMPStreamComeback[397:3f03] VideoStream -> decodeFrame: (ERROR) got_packet = 0, processed_size = -1
  2014-07-30 15:23:31.088 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 320, dropWhiteNoise = 8600, pcm.remaining = 16036
  2014-07-30 15:23:31.090 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 1024, dropWhiteNoise = 7576, pcm.remaining = 16036
  2014-07-30 15:23:31.093 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 2048, dropWhiteNoise = 5528, pcm.remaining = 16036
  2014-07-30 15:23:31.164 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 640, dropWhiteNoise = 4888, pcm.remaining = 16056
  2014-07-30 15:23:31.219 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 128, dropWhiteNoise = 4760, pcm.remaining = 16028
  2014-07-30 15:23:31.298 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 192, dropWhiteNoise = 4568, pcm.remaining = 16036
  2014-07-30 15:23:31.604 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 128, dropWhiteNoise = 4440, pcm.remaining = 16048
  2014-07-30 15:23:31.740 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 320, dropWhiteNoise = 4120, pcm.remaining = 16024
  2014-07-30 15:23:32.296 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 192, dropWhiteNoise = 3928, pcm.remaining = 16008
  2014-07-30 15:24:47.575 RTMPStreamComeback[397:3f03] MPAudioUnitEngine -> dropPcm: *** DROPPED = 64, dropWhiteNoise = 3864, pcm.remaining = 16000
还建议:

Currently the library does not provide an instrument to control the stream quality. This is planned for a future release.

因此,我认为这不可能改变音频流格式

我认为问题可能在于所选的音频编解码器;如果你有能力改变一个选择,我建议尝试mp3在44100kHzThanks Mondain我现在看看
Audio:
codec - Nelly Mozer 16KHz, mono
bitrate - 128000

Video:
codec - H.263 (Sorenson)
bitrate - 200000
resolution - 192x144px
fps = 25
intra frame - 10
Currently the library does not provide an instrument to control the stream quality. This is planned for a future release.