選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

151 行
4.4KB

  1. /*
  2. * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <string.h>
  11. #include "mk_mediakit.h"
  12. typedef struct {
  13. mk_player player;
  14. mk_media media;
  15. mk_pusher pusher;
  16. char push_url[1024];
  17. } Context;
  18. void release_media(mk_media *ptr) {
  19. if (ptr && *ptr) {
  20. mk_media_release(*ptr);
  21. *ptr = NULL;
  22. }
  23. }
  24. void release_player(mk_player *ptr) {
  25. if (ptr && *ptr) {
  26. mk_player_release(*ptr);
  27. *ptr = NULL;
  28. }
  29. }
  30. void release_pusher(mk_media *ptr) {
  31. if (ptr && *ptr) {
  32. mk_pusher_release(*ptr);
  33. *ptr = NULL;
  34. }
  35. }
  36. void release_context(Context **ptr){
  37. if (ptr && *ptr) {
  38. release_pusher(&(*ptr)->pusher);
  39. release_media(&(*ptr)->media);
  40. release_player(&(*ptr)->player);
  41. free(*ptr);
  42. *ptr = NULL;
  43. }
  44. }
  45. void API_CALL on_mk_push_event_func(void *user_data,int err_code,const char *err_msg){
  46. Context *ctx = (Context *) user_data;
  47. if (err_code == 0) {
  48. //push success
  49. log_info("push %s success!", ctx->push_url);
  50. } else {
  51. log_warn("push %s failed:%d %s", ctx->push_url, err_code, err_msg);
  52. release_pusher(&(ctx->pusher));
  53. }
  54. }
  55. void API_CALL on_mk_media_source_regist_func(void *user_data, mk_media_source sender, int regist){
  56. Context *ctx = (Context *) user_data;
  57. const char *schema = mk_media_source_get_schema(sender);
  58. if (strncmp(schema, ctx->push_url, strlen(schema)) == 0) {
  59. //判断是否为推流协议相关的流注册或注销事件
  60. release_pusher(&(ctx->pusher));
  61. if (regist) {
  62. ctx->pusher = mk_pusher_create_src(sender);
  63. mk_pusher_set_on_result(ctx->pusher, on_mk_push_event_func, ctx);
  64. mk_pusher_set_on_shutdown(ctx->pusher, on_mk_push_event_func, ctx);
  65. mk_pusher_publish(ctx->pusher, ctx->push_url);
  66. } else {
  67. log_info("push stoped!");
  68. }
  69. }
  70. }
  71. void API_CALL on_track_frame_out(void *user_data, mk_frame frame) {
  72. Context *ctx = (Context *) user_data;
  73. mk_media_input_frame(ctx->media, frame);
  74. }
  75. void API_CALL on_mk_play_event_func(void *user_data, int err_code, const char *err_msg, mk_track tracks[], int track_count) {
  76. Context *ctx = (Context *) user_data;
  77. release_media(&(ctx->media));
  78. release_pusher(&(ctx->pusher));
  79. if (err_code == 0) {
  80. //success
  81. log_debug("play success!");
  82. ctx->media = mk_media_create("__defaultVhost__", "live", "test", 0, 0, 0);
  83. int i;
  84. for (i = 0; i < track_count; ++i) {
  85. mk_media_init_track(ctx->media, tracks[i]);
  86. mk_track_add_delegate(tracks[i], on_track_frame_out, user_data);
  87. }
  88. mk_media_init_complete(ctx->media);
  89. mk_media_set_on_regist(ctx->media, on_mk_media_source_regist_func, ctx);
  90. } else {
  91. log_warn("play failed: %d %s", err_code, err_msg);
  92. }
  93. }
  94. void context_start(Context *ctx, const char *url_pull, const char *url_push){
  95. release_player(&(ctx->player));
  96. ctx->player = mk_player_create();
  97. mk_player_set_on_result(ctx->player, on_mk_play_event_func, ctx);
  98. mk_player_set_on_shutdown(ctx->player, on_mk_play_event_func, ctx);
  99. mk_player_play(ctx->player, url_pull);
  100. strcpy(ctx->push_url, url_push);
  101. }
  102. int main(int argc, char *argv[]){
  103. mk_config config = {
  104. .ini = NULL,
  105. .ini_is_path = 0,
  106. .log_level = 0,
  107. .log_mask = LOG_CONSOLE,
  108. .ssl = NULL,
  109. .ssl_is_path = 1,
  110. .ssl_pwd = NULL,
  111. .thread_num = 0
  112. };
  113. mk_env_init(&config);
  114. if (argc != 3) {
  115. printf("Usage: ./pusher.c pull_url push_url\n");
  116. return -1;
  117. }
  118. //可以通过
  119. //rtmp://127.0.0.1/live/test
  120. //rtsp://127.0.0.1/live/test
  121. //播放mk_media的数据
  122. mk_rtsp_server_start(554, 0);
  123. mk_rtmp_server_start(1935, 0);
  124. Context *ctx = (Context *) malloc(sizeof(Context));
  125. memset(ctx, 0, sizeof(Context));
  126. //推流给自己测试,当然也可以推流给其他服务器测试
  127. context_start(ctx, argv[1], argv[2]);
  128. log_info("enter any key to exit");
  129. getchar();
  130. release_context(&ctx);
  131. return 0;
  132. }