@Override public void onData(MessageInfo mi, RTMPCommand command) { String handlerName = (String) command.getArguments().get(0); if (HANDLER_NAME_SET_DATA_FRAME.equals(handlerName)) { metaData = (Map) command.getArguments().get(2); System.err.println("metadata: " + command.getArguments()); } else { System.err.println("Unknown data: " + command.getArguments()); } }
@Override public void invokeCommand(MessageInfo mi, RTMPCommand command) { // System.err.println("cmd: " + command.getName() + " " + command.getArguments()); if (command.getName().equals("connect")) { cmdConnect(mi, command); } else if (command.getName().equals("releaseStream")) { sendSuccess(mi, command); } else if (command.getName().equals("FCUnpublish")) { // sendSuccess(mi, command); context.terminate(); } else if (command.getName().equals("createStream")) { cmdCreateStream(mi, command); } else if (command.getName().equals("FCPublish")) { cmdFCPublish(mi, command); } else if (command.getName().equals("publish")) { cmdPublish(mi, command); } else if (command.getName().equals("deleteStream")) { cmdDeleteStream(mi, command); } else { System.err.println("Unknown command: " + command.getName()); sendError(mi, command, null, null); } }
protected void cmdCreateStream(MessageInfo mi, RTMPCommand command) { AMFPacket response = new AMFPacket(); response.writeString("_result"); response.writeNumber(command.getTxid()); response.writeMixed(null); response.writeMixed(1d); context.writeCommand(mi.chunkStreamID, mi.messageStreamID, response); }
protected void sendError(MessageInfo mi, RTMPCommand command, Object object, Object information) { AMFPacket response = new AMFPacket(); response.writeString("_error"); response.writeNumber(command.getTxid()); response.writeMixed(object); response.writeMixed(information); context.writeCommand(mi.chunkStreamID, mi.messageStreamID, response); }
protected void cmdConnect(MessageInfo mi, RTMPCommand command) { AMFPacket response = new AMFPacket(); response.writeString("_result"); response.writeNumber(command.getTxid()); Map<String, Object> arg1 = new HashMap<>(); arg1.put("fmsVer", "FMS/3,5,5,2004"); arg1.put("capabilities", 31d); arg1.put("mode", 1d); response.writeObject(arg1); Map<String, Object> arg2 = new HashMap<>(); arg2.put("level", "status"); arg2.put("code", "NetConnection.Connect.Success"); arg2.put("description", "Connection succeeded"); arg2.put("data", new Object[0]); arg2.put("clientId", 1d); arg2.put("objectEncoding", 0d); response.writeObject(arg2); context.writeCommand(mi.chunkStreamID, mi.messageStreamID, response); }
protected void cmdPublish(MessageInfo mi, RTMPCommand command) { Object arg1 = command.getArguments().get(0); if (!(arg1 instanceof String)) { sendSuccess(mi, command); return; } String streamName = (String) command.getArguments().get(0); int separatorPos = streamName.indexOf(STREAM_NAME_SEPARATOR); if (separatorPos == -1) { Map<String, Object> info = new HashMap<>(); info.put("code", "NetStream.Publish.BadName"); // with lack of better choice info.put("level", "error"); info.put("description", "Stream password required."); terminateWithError(mi, command, null, info); return; } String clientStreamID = streamName.substring(0, separatorPos); String clientSecret = streamName.substring(separatorPos + 1); String streamProperty = props.getProperty("streams." + clientStreamID); if (!"true".equals(streamProperty) && !"1".equals(streamProperty)) { Map<String, Object> info = new HashMap<>(); info.put("code", "NetStream.Publish.BadName"); // with lack of better choice info.put("level", "error"); info.put("description", "Stream does not exist."); terminateWithError(mi, command, null, info); return; } String streamSectret = props.getProperty("streams." + clientStreamID + ".password"); if (streamSectret == null) { Map<String, Object> info = new HashMap<>(); info.put("code", "NetStream.Publish.BadName"); // with lack of better choice info.put("level", "error"); info.put("description", "Stream does not exist."); terminateWithError(mi, command, null, info); return; } if (!clientSecret.equals(streamSectret)) { Map<String, Object> info = new HashMap<>(); info.put("code", "NetStream.Publish.BadName"); // with lack of better choice info.put("level", "error"); info.put("description", "Authentication error."); terminateWithError(mi, command, null, info); return; } // raise limit after successful authentication context.getLimit().assemblyBufferSize = 256 * 1024; context.getLimit().assemblyBufferCount = 16; context.getLimit().chunkStreamCount = 32; streamID = clientStreamID; AMFPacket response = new AMFPacket(); response.writeString("onStatus"); response.writeNumber(fcpublishTxID); response.writeMixed(null); Map<String, Object> arg2 = new HashMap<>(); arg2.put("level", "status"); arg2.put("code", "NetStream.Publish.Start"); arg2.put("description", ""); arg2.put("details", command.getArguments().get(0)); arg2.put("clientId", 1d); arg2.put("objectEncoding", 0d); response.writeObject(arg2); context.writeCommand(mi.chunkStreamID, mi.messageStreamID, response); }
protected void cmdFCPublish(MessageInfo mi, RTMPCommand command) { fcpublishTxID = command.getTxid(); sendSuccess(mi, command); }