问题
So far i almost developed a Flash Air for IOS App and i was 50% done. I got all the live streaming to work with RED5 Media Server but came to a Dead End when i found that the iPhone Camera was displaying 90 degrees so the stream being sent and saved to the RED5 Server was also recorded 90 degrees. I read lots of articles online even on Stack Overflow that this is a known Bug. Not sure when this will be fixed. I also tried some ANE Air Native Extensions that would work the camera rotation in my Air App, these were the DiaDraw and StarlingCamera ANE, but could not find any information tutorial, online so could not get this to work.
Flash Adobe Air for IOS code that connects to RED5 Server and shows tat the iPhone Camera is 90 degrees:
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 server code:
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;
}
}
So Then i decided to stream natively, and i used the Media and CommLib libraries in objective-c and found this code, i pasted this on Pastebin because there was too much code to edit when pasting on here:
This is the RTMP CLIENT which successfully connects to RED5 Java Application Adapter running on another PC.
http://pastebin.com/0KQvTL0b
When running the RTMP CLIENT using Xcode, the App was streaming live but every few seconds the Audio would glitch and i couldn't find anything that could fix this issue, maybe i needed to alter some code but i found this RTMP CLIENT code online and modified the Stream Name and RTMP Url to point to my Application on the RED5 server.
Why does the audio keep glitching. So now i feel like giving WOWZA Media Server a go.
So far i download the Wowza Media Server then installed Eclipse. Once Eclipse was installed i then installed the Wowza IDE which i intalled in Eclipse but make sure you install the Wowza Media Server first before installing the Wowza IDE.
I then found some code online which would be the Server running on the Wowza Server, the new Wowza Server is run in the browser, i tried running this in the Terminal but couldn't get it running as it kept saying "Operation could not run" in the terminal.
This is the code i used for the Server:
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());
}
}
So now i run the Xcode Project the RTMP CLIENT and find that the RTMP CLIENT does connect but i don't get no Live Stream. Just wanted to ask where i need to change my code in order to get the live streaming to work?
Also with my experience using Adobe Air for IOS and using RED5, Should i be taking this last route because I'm not sure. I have researched a lot and really i want to find the no cost way of knowing how to stream from IPhone camera. I have tried Adobe for IOS to RED5 Server and found the there is a known Bug and i have tried Native to RED5 and found the Audio Glitch so is Wowza the best bet?
UPDATE
I get an output in Xcode console that the stream could not be found, here is the output:
2014-07-30 13:33:06.246 RTMPStreamComeback[340:4003] $$$$$$ <MPIMediaStreamEvent> stateChangedEvent: sender = MediaStreamPlayer, 4 = NetStream.Play.StreamNotFound
I have set the UpStream name "tester" and the DownStream name "tester"
Update
The Streaming now works i found this tutorial online and found that i needed to include the Application.xml and configure the file. Here is the tutorial:
https://www.youtube.com/watch?v=XoojcVfdHWg
But again just like RED5 the Audio seems to glitch, but the stream never gets disrupted apart from the audio.
How can i FIX this?
This is the trace from 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
These are the default settings for audio and video format: Default streaming settings are shown below:
Audio:
codec - Nelly Mozer 16KHz, mono
bitrate - 128000
Video:
codec - H.263 (Sorenson)
bitrate - 200000
resolution - 192x144px
fps = 25
intra frame - 10
ALSO SUGGESTS:
Currently the library does not provide an instrument to control the stream quality. This is planned for a future release.
So i dont think this is possible to change the Audio Stream Format
来源:https://stackoverflow.com/questions/25026472/wowza-to-ios-how-to-live-stream