nonocast / me

记录和分享技术的博客
http://nonocast.cn
MIT License
20 stars 0 forks source link

学习 rtmp 开发 (Part 2: hello world) #270

Open nonocast opened 2 years ago

nonocast commented 2 years ago

一档起步

main.c

#include <librtmp/rtmp.h>
#include <stdio.h>

int main() {
  int version = RTMP_LibVersion();
  printf("0x%06x\n", version); // 0x020300 means 2.3
  return 0;
}

Makefile

CC=clang
ARCH=x86_64
CFLAGS=`pkg-config --cflags librtmp`
LDFLAGS=`pkg-config --libs librtmp`

build: src/main.c
    mkdir -p build
    $(CC) -arch ${ARCH} $(CFLAGS) $(LDFLAGS) -o build/app src/main.c

run:  build
    cd build && ./app

clean:
    rm -rf build

.PHONY: build run clean

几个点:

保存到flv

这本身就是rtmpdump的功能,结合雷神的sample,形成如下代码:

main.c

#include <librtmp/rtmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define APP_SUCCESS 0
#define APP_FAILED 1

// rtmpdump -r rtmp://media3.scctv.net/live/scctv_800 -o test.flv
static void usage();
static void parse_args(int, char **, char **, char **);
static void sigIntHandler(int);

int main(int argc, char *argv[]) {
  // data
  FILE *file = 0;
  char *output = "out.flv";
  char *url;
  RTMP rtmp = {0};

  // parse options and arguments
  parse_args(argc, argv, &url, &output);
  printf("rtmp url: %s\n", url);
  printf("output: %s\n", output);
  if (!(file = fopen(output, "wb"))) {
    fprintf(stderr, "Open file FAILED\n");
    exit(APP_FAILED);
  }

  signal(SIGINT, sigIntHandler);

  RTMP_Init(&rtmp);

  if (!RTMP_SetupURL(&rtmp, url)) {
    fprintf(stderr, "RTMP SetupURL FAILED\n");
    return APP_FAILED;
  }

  if (!RTMP_Connect(&rtmp, NULL)) {
    fprintf(stderr, "RTMP Connect FAILED\n");
    RTMP_Close(&rtmp);
    return APP_FAILED;
  }

  if (!RTMP_ConnectStream(&rtmp, 0)) {
    fprintf(stderr, "RTMP ConnectStream FAILED\n");
    RTMP_Close(&rtmp);
    return APP_FAILED;
  }

  int size = 2 * 1024 * 1024; // 2M bytes
  char buffer[size];
  int count;
  int total;

  while (!RTMP_ctrlC && (count = RTMP_Read(&rtmp, buffer, size)) > 0) {
    if (fwrite(buffer, sizeof(char), count, file) != count) {
      fprintf(stderr, "RTMP read FAILED\n");
      break;
    }
    total += count;
    printf("Receive: %5d Byte, Total: %5.2f kB\n", count, total * 1.0 / 1024);
  }

  printf("# EOF");
  fclose(file);
  RTMP_Close(&rtmp);

  return APP_SUCCESS;
}

static void usage() {
  printf("Usage: app -o out.flv rtmp://media3.scctv.net/live/scctv_800\n");
}

static void parse_args(int argc, char *argv[], char **url, char **output) {
  int c;
  while ((c = getopt(argc, argv, "o:")) != -1) {
    switch (c) {
    case 'o':
      *output = optarg;
      break;
    default:
      usage();
      break;
    }
  }

  *url = argv[optind];
  if (*url == NULL) {
    usage();
    exit(APP_FAILED);
  }
}

static void sigIntHandler(int sig) {
  RTMP_ctrlC = TRUE;
  printf("  Caught signal: %d, cleaning up, just a second...\n", sig);
  signal(SIGINT, SIG_IGN);
}

Makefile

CC=clang
ARCH=x86_64
CFLAGS=`pkg-config --cflags librtmp`
LDFLAGS=`pkg-config --libs librtmp`

build: src/main.c
    mkdir -p build
    $(CC) -arch ${ARCH} $(CFLAGS) $(LDFLAGS) -o build/app src/main.c

run: build
    cd build && ./app -o ../out.flv rtmp://your-domain/app/stream

clean:
    rm -rf build

.PHONY: build run clean

通过ffplay out.flv:

ffplay out.flv 
ffplay version 5.0.1 Copyright (c) 2003-2022 the FFmpeg developers
  built with Apple clang version 13.1.6 (clang-1316.0.21.2)
  configuration: --prefix...
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Input #0, flv, from 'out.flv':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42mp41
    encoder         : Lavf59.24.100
    server          : SRS/4.0.251(Leo)
    server_version  : 4.0.251
  Duration: 00:00:06.72, start: 0.021000, bitrate: 4900 kb/s
  Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, 128 kb/s
  Stream #0:1: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080, 30 fps, 30 tbr, 1k tbn

参考阅读