Ejemplo n.º 1
0
static int
rtmp_probe(const char *url0, char *errbuf, size_t errlen, int timeout_ms)
{
  RTMP *r;
  char *url = mystrdupa(url0);

  r = RTMP_Alloc();
  RTMP_Init(r, NULL);

  if(!RTMP_SetupURL(r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  if(!RTMP_Connect(r, NULL, errbuf, errlen, timeout_ms)) {
    RTMP_Close(r);
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  RTMP_SetReadTimeout(r, timeout_ms);

  if(!RTMP_ConnectStream(r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    RTMP_Close(r);
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  RTMP_Close(r);
  RTMP_Free(r);

  return BACKEND_PROBE_OK;
}
/*
 * Class:     net_butterflytv_rtmp_client_RtmpClient
 * Method:    open
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_net_ossrs_sea_RtmpClient_open
        (JNIEnv * env, jobject thiz, jstring url_, jboolean isPublishMode) {

    const char *url = (*env)->GetStringUTFChars(env, url_, 0);
    rtmp = RTMP_Alloc();
    if (rtmp == NULL) {
        return -1;
    }

	RTMP_Init(rtmp);
	int ret = RTMP_SetupURL(rtmp, url);

    if (!ret) {
        RTMP_Free(rtmp);
        return -2;
    }
    if (isPublishMode) {
        RTMP_EnableWrite(rtmp);
    }

	ret = RTMP_Connect(rtmp, NULL);
    if (!ret) {
        RTMP_Free(rtmp);
        return -3;
    }
	ret = RTMP_ConnectStream(rtmp, 0);

    if (!ret) {
        return -4;
    }
    (*env)->ReleaseStringUTFChars(env, url_, url);
    return 1;
}
Ejemplo n.º 3
0
static gboolean
gst_rtmp_sink_start (GstBaseSink * basesink)
{
  GstRTMPSink *sink = GST_RTMP_SINK (basesink);

  if (!sink->uri) {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        ("Please set URI for RTMP output"), ("No URI set before starting"));
    return FALSE;
  }

  sink->rtmp_uri = g_strdup (sink->uri);
  sink->rtmp = RTMP_Alloc ();
  RTMP_Init (sink->rtmp);
  if (!RTMP_SetupURL (sink->rtmp, sink->rtmp_uri)) {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
        ("Failed to setup URL '%s'", sink->uri));
    RTMP_Free (sink->rtmp);
    sink->rtmp = NULL;
    g_free (sink->rtmp_uri);
    sink->rtmp_uri = NULL;
    return FALSE;
  }

  GST_DEBUG_OBJECT (sink, "Created RTMP object");

  /* Mark this as an output connection */
  RTMP_EnableWrite (sink->rtmp);

  sink->first = TRUE;

  return TRUE;
}
Ejemplo n.º 4
0
void RTMPWriter::close() {

  if(rtmp) {
    RTMP_Close(rtmp);
    RTMP_Free(rtmp);
    rtmp = NULL;
  }

}
Ejemplo n.º 5
0
/* open the file, do stuff necessary to go to PAUSED state */
static gboolean
gst_rtmp_src_start (GstBaseSrc * basesrc)
{
  GstRTMPSrc *src;
  gchar *uri_copy;

  src = GST_RTMP_SRC (basesrc);

  if (!src->uri) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No filename given"));
    return FALSE;
  }

  src->cur_offset = 0;
  src->last_timestamp = 0;
  src->discont = TRUE;

  uri_copy = g_strdup (src->uri);
  src->rtmp = RTMP_Alloc ();
  RTMP_Init (src->rtmp);
  if (!RTMP_SetupURL (src->rtmp, uri_copy)) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Failed to setup URL '%s'", src->uri));
    g_free (uri_copy);
    RTMP_Free (src->rtmp);
    src->rtmp = NULL;
    return FALSE;
  }
  src->seekable = !(src->rtmp->Link.lFlags & RTMP_LF_LIVE);
  GST_INFO_OBJECT (src, "seekable %d", src->seekable);

  /* open if required */
  if (!RTMP_IsConnected (src->rtmp)) {
    if (!RTMP_Connect (src->rtmp, NULL)) {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Could not connect to RTMP stream \"%s\" for reading", src->uri));
      RTMP_Free (src->rtmp);
      src->rtmp = NULL;
      return FALSE;
    }
  }

  return TRUE;
}
Ejemplo n.º 6
0
static GstFlowReturn
gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{
  GstRTMPSink *sink = GST_RTMP_SINK (bsink);
  GstBuffer *reffed_buf = NULL;

  if (sink->first) {
    /* open the connection */
    if (!RTMP_IsConnected (sink->rtmp)) {
      if (!RTMP_Connect (sink->rtmp, NULL)
          || !RTMP_ConnectStream (sink->rtmp, 0)) {
        GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
            ("Could not connect to RTMP stream \"%s\" for writing", sink->uri));
        RTMP_Free (sink->rtmp);
        sink->rtmp = NULL;
        g_free (sink->rtmp_uri);
        sink->rtmp_uri = NULL;
        return GST_FLOW_ERROR;
      }
      GST_DEBUG_OBJECT (sink, "Opened connection to %s", sink->rtmp_uri);
    }

    /* FIXME: Parse the first buffer and see if it contains a header plus a packet instead
     * of just assuming it's only the header */
    GST_LOG_OBJECT (sink, "Caching first buffer of size %d for concatenation",
        GST_BUFFER_SIZE (buf));
    gst_buffer_replace (&sink->cache, buf);
    sink->first = FALSE;
    return GST_FLOW_OK;
  }

  if (sink->cache) {
    GST_LOG_OBJECT (sink, "Joining 2nd buffer of size %d to cached buf",
        GST_BUFFER_SIZE (buf));
    gst_buffer_ref (buf);
    reffed_buf = buf = gst_buffer_join (sink->cache, buf);
    sink->cache = NULL;
  }

  GST_LOG_OBJECT (sink, "Sending %d bytes to RTMP server",
      GST_BUFFER_SIZE (buf));

  if (!RTMP_Write (sink->rtmp,
          (char *) GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf))) {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Failed to write data"));
    if (reffed_buf)
      gst_buffer_unref (reffed_buf);
    return GST_FLOW_ERROR;
  }

  if (reffed_buf)
    gst_buffer_unref (reffed_buf);

  return GST_FLOW_OK;
}
Ejemplo n.º 7
0
static CURLcode rtmp_disconnect(struct connectdata *conn,
                                bool dead_connection)
{
    RTMP *r = conn->proto.generic;
    (void)dead_connection;
    if(r) {
        conn->proto.generic = NULL;
        RTMP_Close(r);
        RTMP_Free(r);
    }
    return CURLE_OK;
}
Ejemplo n.º 8
0
static void
rtmp_free(rtmp_t *r)
{
  if(r->vcodec != NULL)
    media_codec_deref(r->vcodec);

  if(r->acodec != NULL)
    media_codec_deref(r->acodec);

  RTMP_Close(r->r);
  RTMP_Free(r->r);
}
Ejemplo n.º 9
0
int main(int argc, char **argv)
{
    RTMP *rtmp=RTMP_Alloc();

    if(!rtmp)
        return 1;

    RTMP_Init(rtmp);
    RTMP_Free(rtmp);

    return 0;
}
Ejemplo n.º 10
0
int rtmp_rvod_stop(t_rtmp_vod_ctx* ctx)
{
    if (!ctx || !ctx->rtmp)
    {
        return -1;
    }
    RTMP *rtmp = ctx->rtmp;
    rtmp_rvod_closefile(ctx);
    RTMP_Close(rtmp);
    RTMP_Free(rtmp);
    return 0;
}
Ejemplo n.º 11
0
LibRtmp::~LibRtmp()
{
    Close();
    RTMP_Free(rtmp_);

    if (streming_url_)
    {
        free(streming_url_);
        streming_url_ = NULL;
    }

    if (flog_) fclose(flog_);
}
Ejemplo n.º 12
0
static CURLcode rtmp_setup_connection(struct connectdata *conn)
{
  RTMP *r = RTMP_Alloc();
  if(!r)
    return CURLE_OUT_OF_MEMORY;

  RTMP_Init(r);
  RTMP_SetBufferMS(r, DEF_BUFTIME);
  if(!RTMP_SetupURL(r, conn->data->change.url)) {
    RTMP_Free(r);
    return CURLE_URL_MALFORMAT;
  }
  conn->proto.generic = r;
  return CURLE_OK;
}
Ejemplo n.º 13
0
RTMPWriter::~RTMPWriter() {

  cb_disconnect = NULL;
  cb_user = NULL;

  if(rtmp && state == RW_STATE_INITIALIZED) {
    RTMP_Close(rtmp);
  }

  if(rtmp) {
    RTMP_Free(rtmp);
    rtmp = NULL;
  }

  state = RW_STATE_NONE;

}
Ejemplo n.º 14
0
void  RtmpSessionFini(RTMP_SESSION *pSession)
{
	if(NULL != pSession->prtmp)
	{
		RTMP_Free(pSession->prtmp);
		pSession->prtmp = NULL;
	}

	if(NULL != pSession->pPkt)
	{
		RTMPPacket_Free(pSession->pPkt);
		free(pSession->pPkt);
		pSession->pPkt = NULL;
	}
	
	return ;	
}
Ejemplo n.º 15
0
static gboolean
gst_rtmp_src_stop (GstBaseSrc * basesrc)
{
  GstRTMPSrc *src;

  src = GST_RTMP_SRC (basesrc);

  if (src->rtmp) {
    RTMP_Free (src->rtmp);
    src->rtmp = NULL;
  }

  src->cur_offset = 0;
  src->last_timestamp = 0;
  src->discont = TRUE;

  return TRUE;
}
Ejemplo n.º 16
0
void sc_streamer_reconnect(sc_streamer *streamer) {
    printf("Reconnecting \n");
    RTMP_Close(streamer->rtmp);
    RTMP_Free(streamer->rtmp);
    streamer->rtmp = open_RTMP_stream( streamer->stream_uri );
    
    streamer->reconnect_tries++;
    
    if(streamer->reconnect_tries >= SC_Reconnect_Attempts) {
        printf("Reconnected failed after %i tries \n", streamer->reconnect_tries);
        if(streamer->so_name != NULL) {
            sc_streamer_stop_cursor(streamer);
        } else {
            sc_streamer_stop_video(streamer);
        }
        exit(1);
    } 
}
Ejemplo n.º 17
0
static gboolean
gst_rtmp_sink_stop (GstBaseSink * basesink)
{
  GstRTMPSink *sink = GST_RTMP_SINK (basesink);

  gst_buffer_replace (&sink->cache, NULL);

  if (sink->rtmp) {
    RTMP_Close (sink->rtmp);
    RTMP_Free (sink->rtmp);
    sink->rtmp = NULL;
  }
  if (sink->rtmp_uri) {
    g_free (sink->rtmp_uri);
    sink->rtmp_uri = NULL;
  }

  return TRUE;
}
Ejemplo n.º 18
0
void RTMPWriter::write(uint8_t* data, size_t nbytes) {

  if(state == RW_STATE_NONE) {
    printf("error: cannot write to rtmp server because we haven't been initialized. did you call initialize()?\n");
    return;
  }
  else if(state == RW_STATE_RECONNECTING) {
    //printf("reconnecting... ignoring data...\n");
    return;
  }
  else if(state == RW_STATE_DISCONNECTED) {
    // the caller needs to call reconnect() 
    return;
  }
  
  //printf("rtmp: %ld\n", nbytes);
  int r = RTMP_Write(rtmp, (const char*)data, (int)nbytes);
  if(r < 0) {

    // @todo - we should close and cleanup here!!!!
    RTMP_Close(rtmp);
    RTMP_Free(rtmp);
    rtmp = NULL;

    printf("error: something went wrong while trying to write data to the rtmp server.\n");
    if(state == RW_STATE_DISCONNECTED) {
      return;
    }
    // when initialized and we arrive here, it means we're disconnected
    else if(state == RW_STATE_INITIALIZED) {

      state = RW_STATE_DISCONNECTED;
      if(cb_disconnect) {
        cb_disconnect(this, cb_user);
      }

    }
  }
}
Ejemplo n.º 19
0
RTMPPublisher::~RTMPPublisher()
{
    bStopping = true;

    //we're in the middle of connecting! wait for that to happen to avoid all manner of race conditions
    if (hConnectionThread)
    {
        WaitForSingleObject(hConnectionThread, INFINITE);
        OSCloseThread(hConnectionThread);
    }

    if(hSendThread)
    {
        ReleaseSemaphore(hSendSempahore, 1, NULL);

        //wake it up in case it's waiting for buffer space
        SetEvent(hBufferSpaceAvailableEvent);
        OSTerminateThread(hSendThread, 20000);
    }

    if(hSendSempahore)
        CloseHandle(hSendSempahore);

    if(hDataMutex)
        OSCloseMutex(hDataMutex);

    while (bufferedPackets.Num()) {
        bufferedPackets[0].data.Clear();
        bufferedPackets.Remove(0);
    }

    //wake up and shut down the buffered sender
    SetEvent(hWriteEvent);
    SetEvent(hBufferEvent);

    if (hSocketThread)
    {
        OSTerminateThread(hSocketThread, 20000);

        //at this point nothing new should be coming in to the buffer, flush out what remains
        FlushDataBuffer();
    }

    if(rtmp)
    {
        //disable the buffered send, so RTMP_Close writes directly to the net
        rtmp->m_bCustomSend = 0;
        RTMP_Close(rtmp);
    }

    if (dataBuffer)
        Free(dataBuffer);

    if (hDataBufferMutex)
        OSCloseMutex(hDataBufferMutex);

    if (hBufferEvent)
        CloseHandle(hBufferEvent);

    if (hBufferSpaceAvailableEvent)
        CloseHandle(hBufferSpaceAvailableEvent);

    if (hWriteEvent)
        CloseHandle(hWriteEvent);

    if(rtmp)
        RTMP_Free(rtmp);

    //--------------------------

    for(UINT i=0; i<queuedPackets.Num(); i++)
        queuedPackets[i].data.Clear();
    queuedPackets.Clear();

    double dBFrameDropPercentage = double(numBFramesDumped)/NumTotalVideoFrames()*100.0;
    double dPFrameDropPercentage = double(numPFramesDumped)/NumTotalVideoFrames()*100.0;

    Log(TEXT("Number of times waited to send: %d, Waited for a total of %d bytes"), totalTimesWaited, totalBytesWaited);

    Log(TEXT("Number of b-frames dropped: %u (%0.2g%%), Number of p-frames dropped: %u (%0.2g%%), Total %u (%0.2g%%)"),
        numBFramesDumped, dBFrameDropPercentage,
        numPFramesDumped, dPFrameDropPercentage,
        numBFramesDumped+numPFramesDumped, dBFrameDropPercentage+dPFrameDropPercentage);

    /*if(totalCalls)
        Log(TEXT("average send time: %u"), totalTime/totalCalls);*/

    strRTMPErrors.Clear();

    //--------------------------
}
Ejemplo n.º 20
0
DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
{
    //------------------------------------------------------
    // set up URL

    bool bRetry = false;
    bool bSuccess = false;
    bool bCanRetry = false;

    String failReason;
    String strBindIP;

    int    serviceID    = AppConfig->GetInt   (TEXT("Publish"), TEXT("Service"));
    String strURL       = AppConfig->GetString(TEXT("Publish"), TEXT("URL"));
    String strPlayPath  = AppConfig->GetString(TEXT("Publish"), TEXT("PlayPath"));

    strURL.KillSpaces();
    strPlayPath.KillSpaces();

    LPSTR lpAnsiURL = NULL, lpAnsiPlaypath = NULL;
    RTMP *rtmp = NULL;

    //--------------------------------
    // unbelievably disgusting hack for elgato devices

    String strOldDirectory;
    UINT dirSize = GetCurrentDirectory(0, 0);
    strOldDirectory.SetLength(dirSize);
    GetCurrentDirectory(dirSize, strOldDirectory.Array());

    OSSetCurrentDirectory(API->GetAppPath());

    //--------------------------------

    if(!strURL.IsValid())
    {
        failReason = TEXT("No server specified to connect to");
        goto end;
    }

    if(serviceID != 0)
    {
        XConfig serverData;
        if(!serverData.Open(TEXT("services.xconfig")))
        {
            failReason = TEXT("Could not open services.xconfig");
            goto end;
        }

        XElement *services = serverData.GetElement(TEXT("services"));
        if(!services)
        {
            failReason = TEXT("Could not find any services in services.xconfig");
            goto end;
        }

        XElement *service = NULL;
        DWORD numServices = services->NumElements();
        for(UINT i=0; i<numServices; i++)
        {
            XElement *curService = services->GetElementByID(i);
            if(curService->GetInt(TEXT("id")) == serviceID)
            {
                service = curService;
                break;
            }
        }

        if(!service)
        {
            failReason = TEXT("Could not find the service specified in services.xconfig");
            goto end;
        }

        XElement *servers = service->GetElement(TEXT("servers"));
        if(!servers)
        {
            failReason = TEXT("Could not find any servers for the service specified in services.xconfig");
            goto end;
        }

        XDataItem *item = servers->GetDataItem(strURL);
        if(!item)
            item = servers->GetDataItemByID(0);

        strURL = item->GetData();

        Log(TEXT("Using RTMP service: %s"), service->GetName());
        Log(TEXT("  Server selection: %s"), strURL.Array());
    }

    //------------------------------------------------------
    // now back to the elgato directory if it needs the directory changed still to function *sigh*

    OSSetCurrentDirectory(strOldDirectory);

    //------------------------------------------------------

    rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);

    RTMP_LogSetCallback(librtmpErrorCallback);

    //RTMP_LogSetLevel(RTMP_LOGERROR);

    lpAnsiURL = strURL.CreateUTF8String();
    lpAnsiPlaypath = strPlayPath.CreateUTF8String();

    if(!RTMP_SetupURL2(rtmp, lpAnsiURL, lpAnsiPlaypath))
    {
        failReason = Str("Connection.CouldNotParseURL");
        goto end;
    }

    char *rtmpUser = AppConfig->GetString(TEXT("Publish"), TEXT("Username")).CreateUTF8String();
    char *rtmpPass = AppConfig->GetString(TEXT("Publish"), TEXT("Password")).CreateUTF8String();

    if (rtmpUser)
    {
        rtmp->Link.pubUser.av_val = rtmpUser;
        rtmp->Link.pubUser.av_len = (int)strlen(rtmpUser);
    }

    if (rtmpPass)
    {
        rtmp->Link.pubPasswd.av_val = rtmpPass;
        rtmp->Link.pubPasswd.av_len = (int)strlen(rtmpPass);
    }

    RTMP_EnableWrite(rtmp); //set it to publish

    rtmp->Link.swfUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.swfUrl.av_val = rtmp->Link.tcUrl.av_val;
    /*rtmp->Link.pageUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.pageUrl.av_val = rtmp->Link.tcUrl.av_val;*/
    rtmp->Link.flashVer.av_val = "FMLE/3.0 (compatible; FMSc/1.0)";
    rtmp->Link.flashVer.av_len = (int)strlen(rtmp->Link.flashVer.av_val);

    //-----------------------------------------

    UINT tcpBufferSize = AppConfig->GetInt(TEXT("Publish"), TEXT("TCPBufferSize"), 64*1024);

    if(tcpBufferSize < 8192)
        tcpBufferSize = 8192;
    else if(tcpBufferSize > 1024*1024)
        tcpBufferSize = 1024*1024;

    rtmp->m_outChunkSize = 4096;//RTMP_DEFAULT_CHUNKSIZE;//
    rtmp->m_bSendChunkSizeInfo = TRUE;

    rtmp->m_bUseNagle = TRUE;

    strBindIP = AppConfig->GetString(TEXT("Publish"), TEXT("BindToIP"), TEXT("Default"));
    if (scmp(strBindIP, TEXT("Default")))
    {
        rtmp->m_bindIP.addr.sin_family = AF_INET;
        rtmp->m_bindIP.addrLen = sizeof(rtmp->m_bindIP.addr);
        if (WSAStringToAddress(strBindIP.Array(), AF_INET, NULL, (LPSOCKADDR)&rtmp->m_bindIP.addr, &rtmp->m_bindIP.addrLen) == SOCKET_ERROR)
        {
            // no localization since this should rarely/never happen
            failReason = TEXT("WSAStringToAddress: Could not parse address");
            goto end;
        }
    }

    LogInterfaceType(rtmp);

    //-----------------------------------------

    if(!RTMP_Connect(rtmp, NULL))
    {
        failReason = Str("Connection.CouldNotConnect");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    if(!RTMP_ConnectStream(rtmp, 0))
    {
        failReason = Str("Connection.InvalidStream");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    //-----------------------------------------

    OSDebugOut(TEXT("Connected: %u\r\n"), OSGetTime());

    publisher->RequestKeyframe(1000);

    //-----------------------------------------

    bSuccess = true;

end:

    if (lpAnsiURL)
        Free(lpAnsiURL);

    if (lpAnsiPlaypath)
        Free(lpAnsiPlaypath);

    if(!bSuccess)
    {
        if(rtmp)
        {
            RTMP_Close(rtmp);
            RTMP_Free(rtmp);
        }

        if(failReason.IsValid())
            App->SetStreamReport(failReason);

        if(!publisher->bStopping)
            PostMessage(hwndMain, OBS_REQUESTSTOP, bCanRetry ? 0 : 1, 0);

        Log(TEXT("Connection to %s failed: %s"), strURL.Array(), failReason.Array());

        publisher->bStopping = true;
    }
    else
    {
        publisher->Init(rtmp, tcpBufferSize);
        publisher->bConnected = true;
        publisher->bConnecting = false;
    }

    return 0;
}
Ejemplo n.º 21
0
RTMPPublisher::~RTMPPublisher()
{
    //OSDebugOut (TEXT("*** ~RTMPPublisher (%d queued, %d buffered, %d data)\n"), queuedPackets.Num(), bufferedPackets.Num(), curDataBufferLen);
    bStopping = true;

    //we're in the middle of connecting! wait for that to happen to avoid all manner of race conditions
    if (hConnectionThread)
    {
        WaitForSingleObject(hConnectionThread, INFINITE);
        OSCloseThread(hConnectionThread);
    }

    //send all remaining buffered packets, this may block since it respects timestamps
    FlushBufferedPackets ();

    //OSDebugOut (TEXT("%d queued after flush\n"), queuedPackets.Num());

    if(hSendThread)
    {
        //this marks the thread to exit after current work is done
        SetEvent(hSendLoopExit);

        //these wake up the thread
        ReleaseSemaphore(hSendSempahore, 1, NULL);
        SetEvent(hBufferSpaceAvailableEvent);

        //wait 50 sec for all data to finish sending
        if (WaitForSingleObject(hSendThread, 50000) == WAIT_TIMEOUT)
        {
            Log(TEXT("~RTMPPublisher: Network appears stalled with %d / %d buffered, dropping connection!"), curDataBufferLen, dataBufferSize);
            FatalSocketShutdown();

            //this will wake up and flush the sendloop if it's still trying to send out stuff
            ReleaseSemaphore(hSendSempahore, 1, NULL);
            SetEvent(hBufferSpaceAvailableEvent);
        }

        OSTerminateThread(hSendThread, 10000);
    }

    if(hSendSempahore)
        CloseHandle(hSendSempahore);

    //OSDebugOut (TEXT("*** ~RTMPPublisher hSendThread terminated (%d queued, %d buffered, %d data)\n"), queuedPackets.Num(), bufferedPackets.Num(), curDataBufferLen);

    if (hSocketThread)
    {
        //mark the socket loop to shut down after the buffer is empty
        SetEvent(hSocketLoopExit);

        //wake it up in case it already is empty
        SetEvent(hBufferEvent);

        //wait 60 sec for it to exit
        OSTerminateThread(hSocketThread, 60000);
    }

    //OSDebugOut (TEXT("*** ~RTMPPublisher hSocketThread terminated (%d queued, %d buffered, %d data)\n"), queuedPackets.Num(), bufferedPackets.Num(), curDataBufferLen);

    if(rtmp)
    {
        if (RTMP_IsConnected(rtmp))
        {
            //at this point nothing should be in the buffer, flush out what remains to the net and make it blocking
            FlushDataBuffer();

            //disable the buffered send, so RTMP_* functions write directly to the net (and thus block)
            rtmp->m_bCustomSend = 0;

            //manually shut down the stream and issue a graceful socket shutdown
            RTMP_DeleteStream(rtmp);

            shutdown(rtmp->m_sb.sb_socket, SD_SEND);

            //this waits for the socket shutdown to complete gracefully
            for (;;)
            {
                char buff[1024];
                int ret;

                ret = recv(rtmp->m_sb.sb_socket, buff, sizeof(buff), 0);
                if (!ret)
                    break;
                else if (ret == -1)
                {
                    Log(TEXT("~RTMPublisher: Received error %d while waiting for graceful shutdown."), WSAGetLastError());
                    break;
                }
            }

            //OSDebugOut(TEXT("Graceful shutdown complete.\n"));
        }

        //this closes the socket if not already done
        RTMP_Close(rtmp);
    }

    if(hDataMutex)
        OSCloseMutex(hDataMutex);

    while (bufferedPackets.Num())
    {
        //this should not happen any more...
        bufferedPackets[0].data.Clear();
        bufferedPackets.Remove(0);
    }

    if (dataBuffer)
        Free(dataBuffer);

    if (hDataBufferMutex)
        OSCloseMutex(hDataBufferMutex);

    if (hBufferEvent)
        CloseHandle(hBufferEvent);

    if (hSendLoopExit)
        CloseHandle(hSendLoopExit);

    if (hSocketLoopExit)
        CloseHandle(hSocketLoopExit);

    if (hSendBacklogEvent)
        CloseHandle(hSendBacklogEvent);

    if (hBufferSpaceAvailableEvent)
        CloseHandle(hBufferSpaceAvailableEvent);

    if (hWriteEvent)
        CloseHandle(hWriteEvent);

    if(rtmp)
    {
        if (rtmp->Link.pubUser.av_val)
            Free(rtmp->Link.pubUser.av_val);
        if (rtmp->Link.pubPasswd.av_val)
            Free(rtmp->Link.pubPasswd.av_val);
        RTMP_Free(rtmp);
    }

    //--------------------------

    for(UINT i=0; i<queuedPackets.Num(); i++)
        queuedPackets[i].data.Clear();
    queuedPackets.Clear();

    double dBFrameDropPercentage = double(numBFramesDumped)/NumTotalVideoFrames()*100.0;
    double dPFrameDropPercentage = double(numPFramesDumped)/NumTotalVideoFrames()*100.0;

    if (totalSendCount)
        Log(TEXT("Average send payload: %d bytes, average send interval: %d ms"), (DWORD)(totalSendBytes / totalSendCount), totalSendPeriod / totalSendCount);

    Log(TEXT("Number of times waited to send: %d, Waited for a total of %d bytes"), totalTimesWaited, totalBytesWaited);

    Log(TEXT("Number of b-frames dropped: %u (%0.2g%%), Number of p-frames dropped: %u (%0.2g%%), Total %u (%0.2g%%)"),
        numBFramesDumped, dBFrameDropPercentage,
        numPFramesDumped, dPFrameDropPercentage,
        numBFramesDumped+numPFramesDumped, dBFrameDropPercentage+dPFrameDropPercentage);

    /*if(totalCalls)
        Log(TEXT("average send time: %u"), totalTime/totalCalls);*/

    strRTMPErrors.Clear();

    //--------------------------
}
Ejemplo n.º 22
0
RTMPPublisher::~RTMPPublisher()
{
    //OSDebugOut (TEXT("*** ~RTMPPublisher (%d queued, %d buffered)\n"), queuedPackets.Num(), bufferedPackets.Num());
    bStopping = true;

    //we're in the middle of connecting! wait for that to happen to avoid all manner of race conditions
    if (hConnectionThread)
    {
        WaitForSingleObject(hConnectionThread, INFINITE);
        OSCloseThread(hConnectionThread);
    }

    FlushBufferedPackets ();

    //OSDebugOut (TEXT("%d queued after flush\n"), queuedPackets.Num());

    if(hSendThread)
    {
        //this marks the thread to exit after current work is done
        SetEvent(hSendLoopExit);

        //this wakes up the thread
        ReleaseSemaphore(hSendSempahore, 1, NULL);

        //wait 60 sec for it to exit
        OSTerminateThread(hSendThread, 60000);
    }

    if(hSendSempahore)
        CloseHandle(hSendSempahore);

    //OSDebugOut (TEXT("*** ~RTMPPublisher hSendThread terminated (%d queued, %d buffered, %d data)\n"), queuedPackets.Num(), bufferedPackets.Num(), curDataBufferLen);

    if (hSocketThread)
    {
        //mark the socket loop to shut down after the buffer is empty
        SetEvent(hSocketLoopExit);

        //wait 60 sec for it to exit
        OSTerminateThread(hSocketThread, 60000);
    }

    //OSDebugOut (TEXT("*** ~RTMPPublisher hSocketThread terminated (%d queued, %d buffered, %d data)\n"), queuedPackets.Num(), bufferedPackets.Num(), curDataBufferLen);

    if(rtmp)
    {
        //at this point nothing should be in the buffer, flush out what remains and make it blocking
        FlushDataBuffer();

        //disable the buffered send, so RTMP_Close writes directly to the net
        rtmp->m_bCustomSend = 0;

        //ideally we need some kind of delay here, since we just dumped several seconds worth of timestamps to the network
        //at once, and Twitch at shows the offline screen as soon as the connection is severed even if there are
        //pending video frames.

        if (RTMP_IsConnected(rtmp))
            Sleep (500);    //for now
        RTMP_Close(rtmp);
    }

    if(hDataMutex)
        OSCloseMutex(hDataMutex);

    while (bufferedPackets.Num())
    {
        //this should not happen any more...
        bufferedPackets[0].data.Clear();
        bufferedPackets.Remove(0);
    }

    if (dataBuffer)
        Free(dataBuffer);

    if (hDataBufferMutex)
        OSCloseMutex(hDataBufferMutex);

    if (hBufferEvent)
        CloseHandle(hBufferEvent);

    if (hSendLoopExit)
        CloseHandle(hSendLoopExit);

    if (hSocketLoopExit)
        CloseHandle(hSocketLoopExit);

    if (hSendBacklogEvent)
        CloseHandle(hSendBacklogEvent);

    if (hBufferSpaceAvailableEvent)
        CloseHandle(hBufferSpaceAvailableEvent);

    if (hWriteEvent)
        CloseHandle(hWriteEvent);

    if(rtmp)
        RTMP_Free(rtmp);

    //--------------------------

    for(UINT i=0; i<queuedPackets.Num(); i++)
        queuedPackets[i].data.Clear();
    queuedPackets.Clear();

    double dBFrameDropPercentage = double(numBFramesDumped)/NumTotalVideoFrames()*100.0;
    double dPFrameDropPercentage = double(numPFramesDumped)/NumTotalVideoFrames()*100.0;

    Log(TEXT("Number of times waited to send: %d, Waited for a total of %d bytes"), totalTimesWaited, totalBytesWaited);

    Log(TEXT("Number of b-frames dropped: %u (%0.2g%%), Number of p-frames dropped: %u (%0.2g%%), Total %u (%0.2g%%)"),
        numBFramesDumped, dBFrameDropPercentage,
        numPFramesDumped, dPFrameDropPercentage,
        numBFramesDumped+numPFramesDumped, dBFrameDropPercentage+dPFrameDropPercentage);

    /*if(totalCalls)
        Log(TEXT("average send time: %u"), totalTime/totalCalls);*/

    strRTMPErrors.Clear();

    //--------------------------
}
Ejemplo n.º 23
0
int main(int argc, char *argv[])
{
	struct stat sb;
	int opt, i;
	int chapter = 0, available = 0;
	char *book = NULL;
	char audio[256];
	
	while ((opt = getopt(argc, argv, "v:a:b:c:l")) != -1) {
		switch (opt) {
			case 'v':
				version = optarg;
				break;
			case 'a':
				author = optarg;
				break;
			case 'b':
				book = optarg;
				break;
			case 'c':
				chapter = atoi(optarg);
				break;
			case 'l':
				return list();
		} 
	}

	sprintf(audio, "%s-%s", version, author);
	for (i = 0; i < ARRAY_SIZE(audios); i++) {
		if (strcasecmp(audios[i].audio, audio) == 0) {
			available = 1;
			break;
		}
	}
	if (!available) {
		fprintf(stderr, "Invalid version `%s' or author `%s'\n", version, author);
		return EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(books); i++) {
		if (!book || strcasecmp(books[i].osis, book) == 0) {
			available = 1;
			break;
		}
	}

	if (!available) {
		fprintf(stderr, "Invalid book `%s'\n", book);
		return EINVAL;
	}

	if ((rtmp = RTMP_Alloc()) == NULL || (buffer = malloc(BUFSIZ)) == NULL) {
		perror("malloc");
		return ENOMEM;
	}

	if (stat(audio, &sb) == -1) {
		if (errno == ENOENT) {
			mkdir(audio, 0755);
		} else {
			perror("stat");
			return errno;
		}
	} else if (!S_ISDIR(sb.st_mode)) {
		fprintf(stderr, "%s is not a directory\n", audio);
		return errno;
	}

	if (book) {
		if (chapter > books[i].chapter) {
			fprintf(stderr, "Invalid chapter `%d'\n", chapter);
			return EINVAL;
		}
		if (chapter) {
			download(books[i].osis, chapter);
		} else {
			for (chapter = 1; chapter <= books[i].chapter; chapter++) {
				download(books[i].osis, chapter);
			}
		}
		
	} else {
		for (i = 0; i < ARRAY_SIZE(books); i++) {
			for (chapter = 1; chapter <= books[i].chapter; chapter++) {
				download(books[i].osis, chapter);
			}
		}
	}

	RTMP_Free(rtmp);
	free(buffer);

	return 0;
}
Ejemplo n.º 24
0
//Publish using RTMP_SendPacket()  
int publish_using_packet(){  
	RTMP *rtmp=NULL;                             
	RTMPPacket *packet=NULL;  
	uint32_t start_time=0;  
	uint32_t now_time=0;  
	//the timestamp of the previous frame  
	long pre_frame_time=0;  
	long lasttime=0;  
	int bNextIsKey=1;  
	uint32_t preTagsize=0;  

	//packet attributes  
	uint32_t type=0;                          
	uint32_t datalength=0;             
	uint32_t timestamp=0;             
	uint32_t streamid=0;                          

	FILE*fp=NULL;  
	fp=fopen("../live.flv","rb");  
	if (!fp){  
		RTMP_LogPrintf("Open File Error.\n");  
	//	CleanupSockets();  
		return -1;  
	}  

	/* set log level */  
	//RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
	//RTMP_LogSetLevel(loglvl);  

//	if (!InitSockets()){  
//		RTMP_LogPrintf("Init Socket Err\n");  
//		return -1;  
//	}  

	rtmp=RTMP_Alloc();  
	RTMP_Init(rtmp);  
	//set connection timeout,default 30s  
	rtmp->Link.timeout=5;                        
	if(!RTMP_SetupURL(rtmp,"rtmp://101.251.251.93:1935/myapp/mystream"))  
	{  
		RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	//if unable,the AMF command would be 'play' instead of 'publish'  
	RTMP_EnableWrite(rtmp);       

	if (!RTMP_Connect(rtmp,NULL)){  
		RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	if (!RTMP_ConnectStream(rtmp,0)){  
		RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
		RTMP_Close(rtmp);  
		RTMP_Free(rtmp);  
//		CleanupSockets();  
		return -1;  
	}  

	packet=(RTMPPacket*)malloc(sizeof(RTMPPacket));  
	RTMPPacket_Alloc(packet,1024*64);  
	RTMPPacket_Reset(packet);  

	packet->m_hasAbsTimestamp = 0;          
	packet->m_nChannel = 0x04;  
	packet->m_nInfoField2 = rtmp->m_stream_id;  

	RTMP_LogPrintf("Start to send data ...\n");  

	//jump over FLV Header  
	fseek(fp,9,SEEK_SET);       
	//jump over previousTagSizen  
	fseek(fp,4,SEEK_CUR);     
	start_time=RTMP_GetTime();  
	while(1)  
	{  
		if((((now_time=RTMP_GetTime())-start_time)  
					<(pre_frame_time)) && bNextIsKey){          
			//wait for 1 sec if the send process is too fast  
			//this mechanism is not very good,need some improvement  
			if(pre_frame_time>lasttime){  
				RTMP_LogPrintf("TimeStamp:%8lu ms\n",pre_frame_time);  
				lasttime=pre_frame_time;  
			}  
			sleep(1);  
			continue;  
		}  

		//not quite the same as FLV spec  
		if(!ReadU8(&type,fp))       
			break;  
		if(!ReadU24(&datalength,fp))  
			break;  
		if(!ReadTime(&timestamp,fp))  
			break;  
		if(!ReadU24(&streamid,fp))  
			break;  

		if (type!=0x08&&type!=0x09){  
			//jump over non_audio and non_video frame,  
			//jump over next previousTagSizen at the same time  
			fseek(fp,datalength+4,SEEK_CUR);  
			continue;  
		}  

		if(fread(packet->m_body,1,datalength,fp)!=datalength)  
			break;  

		packet->m_headerType = RTMP_PACKET_SIZE_LARGE;  
		packet->m_nTimeStamp = timestamp;  
		packet->m_packetType = type;  
		packet->m_nBodySize  = datalength;  
		pre_frame_time=timestamp;  

		if (!RTMP_IsConnected(rtmp)){  
			RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
			break;  
		}  
		if (!RTMP_SendPacket(rtmp,packet,0)){  
			RTMP_Log(RTMP_LOGERROR,"Send Error\n");  
			break;  
		}  

		if(!ReadU32(&preTagsize,fp))  
			break;  

		if(!PeekU8(&type,fp))  
			break;  
		if(type==0x09){  
			if(fseek(fp,11,SEEK_CUR)!=0)  
				break;  
			if(!PeekU8(&type,fp)){  
				break;  
			}  
			if(type==0x17)  
				bNextIsKey=1;  
			else  
				bNextIsKey=0;  

			fseek(fp,-11,SEEK_CUR);  
		}  
	}                 

	RTMP_LogPrintf("\nSend Data Over\n");  

	if(fp)  
		fclose(fp);  

	if (rtmp!=NULL){  
		RTMP_Close(rtmp);          
		RTMP_Free(rtmp);   
		rtmp=NULL;  
	}  
	if (packet!=NULL){  
		RTMPPacket_Free(packet);      
		free(packet);  
		packet=NULL;  
	}  

//	CleanupSockets();  
	return 0;  
}  
Ejemplo n.º 25
0
//Publish using RTMP_Write()  
int publish_using_write(){  
	uint32_t start_time=0;  
	uint32_t now_time=0;  
	uint32_t pre_frame_time=0;  
	uint32_t lasttime=0;  
	int bNextIsKey=0;  
	char* pFileBuf=NULL;  

	//read from tag header  
	uint32_t type=0;  
	uint32_t datalength=0;  
	uint32_t timestamp=0;  

	RTMP *rtmp=NULL;                             

	FILE*fp=NULL;  
	fp=fopen("cuc_ieschool.flv","rb");  
	if (!fp){  
		RTMP_LogPrintf("Open File Error.\n");  
//		CleanupSockets();  
		return -1;  
	}  

	/* set log level */  
	//RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
	//RTMP_LogSetLevel(loglvl);  

//	if (!InitSockets()){  
//		RTMP_LogPrintf("Init Socket Err\n");  
//		return -1;  
//	}  

	rtmp=RTMP_Alloc();  
	RTMP_Init(rtmp);  
	//set connection timeout,default 30s  
	rtmp->Link.timeout=5;                        
	if(!RTMP_SetupURL(rtmp,"rtmp://localhost/publishlive/livestream"))  
	{  
		RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	RTMP_EnableWrite(rtmp);  
	//1hour  
	RTMP_SetBufferMS(rtmp, 3600*1000);           
	if (!RTMP_Connect(rtmp,NULL)){  
		RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
		RTMP_Free(rtmp);  
//		CleanupSockets();  
		return -1;  
	}  

	if (!RTMP_ConnectStream(rtmp,0)){  
		RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
		RTMP_Close(rtmp);  
		RTMP_Free(rtmp);  
		//CleanupSockets();  
		return -1;  
	}  

	printf("Start to send data ...\n");  

	//jump over FLV Header  
	fseek(fp,9,SEEK_SET);       
	//jump over previousTagSizen  
	fseek(fp,4,SEEK_CUR);     
	start_time=RTMP_GetTime();  
	while(1)  
	{  
		if((((now_time=RTMP_GetTime())-start_time)  
					<(pre_frame_time)) && bNextIsKey){          
			//wait for 1 sec if the send process is too fast  
			//this mechanism is not very good,need some improvement  
			if(pre_frame_time>lasttime){  
				RTMP_LogPrintf("TimeStamp:%8lu ms\n", pre_frame_time);  
				lasttime=pre_frame_time;  
			}  
			sleep(1);  
			continue;  
		}  

		//jump over type  
		fseek(fp,1,SEEK_CUR);     
		if(!ReadU24(&datalength,fp))  
			break;  
		if(!ReadTime(&timestamp,fp))  
			break;  
		//jump back  
		fseek(fp,-8,SEEK_CUR);    

		pFileBuf=(char*)malloc(11+datalength+4);  
		memset(pFileBuf,0,11+datalength+4);  
		if(fread(pFileBuf,1,11+datalength+4,fp)!=(11+datalength+4))  
			break;  

		pre_frame_time=timestamp;  

		if (!RTMP_IsConnected(rtmp)){  
			RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
			break;  
		}  
		if (!RTMP_Write(rtmp,pFileBuf,11+datalength+4)){  
			RTMP_Log(RTMP_LOGERROR,"Rtmp Write Error\n");  
			break;  
		}  

		free(pFileBuf);  
		pFileBuf=NULL;  

		if(!PeekU8(&type,fp))  
			break;  
		if(type==0x09){  
			if(fseek(fp,11,SEEK_CUR)!=0)  
				break;  
			if(!PeekU8(&type,fp)){  
				break;  
			}  
			if(type==0x17)  
				bNextIsKey=1;  
			else  
				bNextIsKey=0;  
			fseek(fp,-11,SEEK_CUR);  
		}  
	}  

	RTMP_LogPrintf("\nSend Data Over\n");  

	if(fp)  
		fclose(fp);  

	if (rtmp!=NULL){  
		RTMP_Close(rtmp);          
		RTMP_Free(rtmp);  
		rtmp=NULL;  
	}  

	if(pFileBuf){  
		free(pFileBuf);  
		pFileBuf=NULL;  
	}  

	//CleanupSockets();  
	return 0;  
}  
Ejemplo n.º 26
0
static GstFlowReturn
gst_rtmp_sink_render (GstBaseSink * bsink, GstBuffer * buf)
{
  GstRTMPSink *sink = GST_RTMP_SINK (bsink);
  GstBuffer *reffed_buf = NULL;
  GstMapInfo map;

  if (sink->first) {
    /* open the connection */
    if (!RTMP_IsConnected (sink->rtmp)) {
      if (!RTMP_Connect (sink->rtmp, NULL)
          || !RTMP_ConnectStream (sink->rtmp, 0)) {
        GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
            ("Could not connect to RTMP stream \"%s\" for writing", sink->uri));
        RTMP_Free (sink->rtmp);
        sink->rtmp = NULL;
        g_free (sink->rtmp_uri);
        sink->rtmp_uri = NULL;
        return GST_FLOW_ERROR;
      }
      GST_DEBUG_OBJECT (sink, "Opened connection to %s", sink->rtmp_uri);
    }

    /* FIXME: Parse the first buffer and see if it contains a header plus a packet instead
     * of just assuming it's only the header */
    GST_LOG_OBJECT (sink, "Caching first buffer of size %" G_GSIZE_FORMAT
        " for concatenation", gst_buffer_get_size (buf));
    gst_buffer_replace (&sink->cache, buf);
    sink->first = FALSE;
    return GST_FLOW_OK;
  }

  if (sink->cache) {
    GST_LOG_OBJECT (sink, "Joining 2nd buffer of size %" G_GSIZE_FORMAT
        " to cached buf", gst_buffer_get_size (buf));
    gst_buffer_ref (buf);
    reffed_buf = buf = gst_buffer_append (sink->cache, buf);
    sink->cache = NULL;
  }

  GST_LOG_OBJECT (sink, "Sending %" G_GSIZE_FORMAT " bytes to RTMP server",
      gst_buffer_get_size (buf));

  gst_buffer_map (buf, &map, GST_MAP_READ);

  if (RTMP_Write (sink->rtmp, (char *) map.data, map.size) <= 0)
    goto write_failed;

  gst_buffer_unmap (buf, &map);
  if (reffed_buf)
    gst_buffer_unref (reffed_buf);

  return GST_FLOW_OK;

  /* ERRORS */
write_failed:
  {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL), ("Failed to write data"));
    gst_buffer_unmap (buf, &map);
    if (reffed_buf)
      gst_buffer_unref (reffed_buf);
    return GST_FLOW_ERROR;
  }
}
Ejemplo n.º 27
0
/*
 * Class:     net_butterflytv_rtmp_client_RtmpClient
 * Method:    close
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_net_ossrs_sea_RtmpClient_close
        (JNIEnv * env, jobject thiz) {
	RTMP_Close(rtmp);
	RTMP_Free(rtmp);
    return 0;
}
Ejemplo n.º 28
0
int main(int argc, char* argv[])
{
    InitSockets();

    double duration = -1;
    int nRead;
    //is live stream ?
    bool bLiveStream = TRUE;

    int bufsize = 1024 * 1024 * 10;
    char *buf = (char*)malloc(bufsize);
    memset(buf, 0, bufsize);
    long countbufsize = 0;

    FILE *fp = fopen("receive.flv", "wb");
    if (!fp)
    {
        RTMP_LogPrintf("Open File Error.\n");
        CleanupSockets();
        return -1;
    }

    /* set log level */
    RTMP_LogLevel loglvl = RTMP_LOGDEBUG;
    RTMP_LogSetLevel(loglvl);

    RTMP *rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);
    //set connection timeout,default 30s
    rtmp->Link.timeout = 10;

	char* rtmpFilePath = "d:\\rtmp.raw";
	rtmp->m_pRTMPFile = fopen(rtmpFilePath,"rb");
	if (!rtmp->m_pRTMPFile)
	{
		RTMP_LogPrintf("Failed to open File :%s\n", rtmpFilePath);
		return FALSE;
	}

	// HKS's live URL
	if(!RTMP_SetupURL(rtmp, "rtmp://live.hkstv.hk.lxdns.com/live/hks"))
    {
        RTMP_Log(RTMP_LOGERROR, "SetupURL Err\n");
        RTMP_Free(rtmp);
        CleanupSockets();
        return -1;
    }
    if (bLiveStream)
    {
        rtmp->Link.lFlags |= RTMP_LF_LIVE;
    }

    //1hour
    RTMP_SetBufferMS(rtmp, 3600 * 1000);

    if(!RTMP_Connect(rtmp, NULL))
    {
        RTMP_Log(RTMP_LOGERROR, "Connect Err\n");
        RTMP_Free(rtmp);
        CleanupSockets();
        return -1;
    }

    if(!RTMP_ConnectStream(rtmp, 0))
    {
        RTMP_Log(RTMP_LOGERROR, "ConnectStream Err\n");
        RTMP_Close(rtmp);
        RTMP_Free(rtmp);
        CleanupSockets();
        return -1;
    }

    while(nRead = RTMP_Read(rtmp, buf, bufsize))
    {
        fwrite(buf, 1, nRead, fp);

        countbufsize += nRead;
        RTMP_LogPrintf("Receive: %5dByte, Total: %5.2fkB\n", nRead, countbufsize * 1.0 / 1024);
    }

    if(fp)
        fclose(fp);

    if(fpPcap)
        fclose(fpPcap);

	if (rtmp->m_pRTMPFile)
	{
		fclose(rtmp->m_pRTMPFile);
	}

    if(buf)
    {
        free(buf);
    }

    if(rtmp)
    {
        RTMP_Close(rtmp);
        RTMP_Free(rtmp);
        CleanupSockets();
        rtmp = NULL;
    }
    return 0;
}
Ejemplo n.º 29
0
int main (int argc, char **argv) {
	char *url;
	int brate = 32;
	int c;
	while ((c = getopt(argc, argv, "u:b:")) != -1)
		switch (c) {
			case 'u':
				url = strdup(optarg);
				break;
			case 'b':
				brate = atoi(optarg);
				break;
			default:
				abort();
		}
// libev
	loop = ev_default_loop(0);
	ev_signal_init(&sigint_sig, sigint_cb, SIGINT);
	ev_signal_start (loop, &sigint_sig);
	ev_async_init(&async, send_cb);
	ev_async_start(loop, &async);

// jack
	jack_status_t status;
	ringbuf = jack_ringbuffer_create(buffer_size);
	framebuf = malloc(buffer_samples * sizeof(jack_default_audio_sample_t));
	client = jack_client_open("jack2rtmp", JackNullOption, &status);
	if (client == NULL) {
		fprintf(stderr, "jack server not running?\n");
		return EXIT_FAILURE;
	}
	jack_on_shutdown(client, jack_shutdown, NULL);
	jack_set_process_callback(client, jack_callback, NULL);
	//jack_set_latency_callback(client, jack_latency_callback, NULL);
	output_port = jack_port_register(client, "1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	//jack_port_register(client, "2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	if (jack_activate(client)) {
		fprintf(stderr, "cannot activate client");
	}

// lame
	mp3 = lame_init();
	lame_set_num_channels(mp3, 1);
	lame_set_mode(mp3, MONO);
	lame_set_in_samplerate(mp3, 48000);
	lame_set_out_samplerate(mp3, 44100);
	lame_set_quality(mp3, 2); // 0=best (very slow), 9=worst.
	lame_set_brate(mp3, brate);
	lame_init_params(mp3);

// rtmp
	rtmp_o = RTMP_Alloc();
	if (rtmp_o == NULL) {
		fprintf(stderr, "RTMP_Alloc\n");
		return EXIT_FAILURE;
	}
	RTMP_Init(rtmp_o);
	RTMP_SetupURL(rtmp_o, url);
	RTMP_EnableWrite(rtmp_o);
	if (!RTMP_Connect(rtmp_o, NULL) || !RTMP_ConnectStream(rtmp_o, 0)) {
		RTMP_Free(rtmp_o);
		fprintf(stderr, "Can not connect.\n");
		return EXIT_FAILURE;
	} else {
		fprintf(stderr, "Connected.\n");
	}

/*
	char *rtmp_buffer = malloc(4096);
	char *rtmp_top = rtmp_buffer + RTMP_MAX_HEADER_SIZE;
	char *outend = rtmp_buffer + 4096;
	*rtmp_top = (uint8_t) AMF_STRING;
	rtmp_top++;
	rtmp_top = put_amf_string(rtmp_top, "@setDataFrame");
	*rtmp_top = (uint8_t) AMF_STRING;
	rtmp_top++;
	rtmp_top = put_amf_string(rtmp_top, "onMetaData");

	// описание объекта
	*rtmp_top = (uint8_t) 8;
	rtmp_top++;
	rtmp_top = AMF_EncodeInt32(rtmp_top, outend, 8);
	// содержимое объекта
	rtmp_top = put_amf_string(rtmp_top, "duration");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 0);
	rtmp_top = put_amf_string(rtmp_top, "audiodatarate");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, brate);
	rtmp_top = put_amf_string(rtmp_top, "audiosamplerate");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 44100);
	rtmp_top = put_amf_string(rtmp_top, "audiosamplesize");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 16);
	rtmp_top = put_amf_string(rtmp_top, "stereo");
	rtmp_top = AMF_EncodeBoolean(rtmp_top, outend, FALSE);
	rtmp_top = put_amf_string(rtmp_top, "audiocodecid");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 2);
	rtmp_top = put_amf_string(rtmp_top, "encoder");
	*rtmp_top = (uint8_t) AMF_STRING;
	rtmp_top++;
	rtmp_top = put_amf_string(rtmp_top, "Lavf53.21.1");
	rtmp_top = put_amf_string(rtmp_top, "filesize");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 0);
	// конец объекта
	rtmp_top = put_amf_string(rtmp_top, "");
	*rtmp_top = (uint8_t) AMF_OBJECT_END;
	rtmp_top++;

	rtmp_w.m_headerType = RTMP_PACKET_SIZE_LARGE;
	rtmp_w.m_nChannel = 0x04; // source channel
	rtmp_w.m_nBodySize = rtmp_top - rtmp_buffer - RTMP_MAX_HEADER_SIZE;
	rtmp_w.m_packetType = RTMP_PACKET_TYPE_INFO;
	rtmp_w.m_nInfoField2 = rtmp_o->m_stream_id;
	rtmp_w.m_body = rtmp_buffer + RTMP_MAX_HEADER_SIZE;
	if ( !RTMP_SendPacket(rtmp_o, &rtmp_w, TRUE) ) {
		fprintf(stderr, "RTMP_SendPacket error\n");
	}
	free(rtmp_buffer);
*/

	int off = 0;
	setsockopt(RTMP_Socket(rtmp_o), SOL_TCP, TCP_NODELAY, &off, sizeof(off));




	rtmp_i = TRUE;
	ev_loop(loop, 0);


	jack_ringbuffer_free(ringbuf);
	//jack_client_close(client);
	return EXIT_SUCCESS;
}
Ejemplo n.º 30
0
void doServe(STREAMING_SERVER * server,	// server socket and state (our listening socket)
	int sockfd	// client connection socket
	)
{
	server->state = STREAMING_IN_PROGRESS;

	RTMP *rtmp = RTMP_Alloc();		/* our session with the real client */
	RTMPPacket packet = { 0 };

	// timeout for http requests
	fd_set fds;
	struct timeval tv;

	memset(&tv, 0, sizeof(struct timeval));
	tv.tv_sec = 5;

	FD_ZERO(&fds);
	FD_SET(sockfd, &fds);

	if (select(sockfd + 1, &fds, NULL, NULL, &tv) <= 0)
	{
		RTMP_Log(RTMP_LOGERROR, "Request timeout/select failed, ignoring request");
		goto quit;
	}
	else
	{
		RTMP_Init(rtmp);
		rtmp->m_sb.sb_socket = sockfd;
		if (sslCtx && !RTMP_TLS_Accept(rtmp, sslCtx))
		{
			RTMP_Log(RTMP_LOGERROR, "TLS handshake failed");
			goto cleanup;
		}
		if (!RTMP_Serve(rtmp))
		{
			RTMP_Log(RTMP_LOGERROR, "Handshake failed");
			goto cleanup;
		}
	}
	server->arglen = 0;
	while (RTMP_IsConnected(rtmp) && RTMP_ReadPacket(rtmp, &packet))
	{
		if (!RTMPPacket_IsReady(&packet))
			continue;
		ServePacket(server, rtmp, &packet);
		RTMPPacket_Free(&packet);
	}

cleanup:
	RTMP_LogPrintf("Closing connection... ");
	RTMP_Close(rtmp);
	/* Should probably be done by RTMP_Close() ... */
	rtmp->Link.playpath.av_val = NULL;
	rtmp->Link.tcUrl.av_val = NULL;
	rtmp->Link.swfUrl.av_val = NULL;
	rtmp->Link.pageUrl.av_val = NULL;
	rtmp->Link.app.av_val = NULL;
	rtmp->Link.flashVer.av_val = NULL;
	if (rtmp->Link.usherToken.av_val)
	{
		free(rtmp->Link.usherToken.av_val);
		rtmp->Link.usherToken.av_val = NULL;
	}
	RTMP_Free(rtmp);
	RTMP_LogPrintf("done!\n\n");

quit:
	if (server->state == STREAMING_IN_PROGRESS)
		server->state = STREAMING_ACCEPTING;

	return;
}