res_convert.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2005, 2006, Digium, Inc.
  5. *
  6. * redice li <redice_li@yahoo.com>
  7. * Russell Bryant <russell@digium.com>
  8. *
  9. * See http://www.asterisk.org for more information about
  10. * the Asterisk project. Please do not directly contact
  11. * any of the maintainers of this project for assistance;
  12. * the project provides a web site, mailing lists and IRC
  13. * channels for your use.
  14. *
  15. * This program is free software, distributed under the terms of
  16. * the GNU General Public License Version 2. See the LICENSE file
  17. * at the top of the source tree.
  18. */
  19. /*! \file
  20. *
  21. * \brief file format conversion CLI command using Asterisk formats and translators
  22. *
  23. * \author redice li <redice_li@yahoo.com>
  24. * \author Russell Bryant <russell@digium.com>
  25. *
  26. */
  27. /*** MODULEINFO
  28. <support_level>core</support_level>
  29. ***/
  30. #include "asterisk.h"
  31. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  32. #include "asterisk/channel.h"
  33. #include "asterisk/module.h"
  34. #include "asterisk/cli.h"
  35. #include "asterisk/file.h"
  36. /*! \brief Split the filename to basename and extension */
  37. static int split_ext(char *filename, char **name, char **ext)
  38. {
  39. *name = *ext = filename;
  40. if ((*ext = strrchr(filename, '.'))) {
  41. **ext = '\0';
  42. (*ext)++;
  43. }
  44. if (ast_strlen_zero(*name) || ast_strlen_zero(*ext))
  45. return -1;
  46. return 0;
  47. }
  48. /*!
  49. * \brief Convert a file from one format to another
  50. * \param e CLI entry
  51. * \param cmd command number
  52. * \param a list of cli arguments
  53. * \retval CLI_SUCCESS on success.
  54. * \retval CLI_SHOWUSAGE or CLI_FAILURE on failure.
  55. */
  56. static char *handle_cli_file_convert(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  57. {
  58. char *ret = CLI_FAILURE;
  59. struct ast_filestream *fs_in = NULL, *fs_out = NULL;
  60. struct ast_frame *f;
  61. struct timeval start;
  62. int cost;
  63. char *file_in = NULL, *file_out = NULL;
  64. char *name_in, *ext_in, *name_out, *ext_out;
  65. switch (cmd) {
  66. case CLI_INIT:
  67. e->command = "file convert";
  68. e->usage =
  69. "Usage: file convert <file_in> <file_out>\n"
  70. " Convert from file_in to file_out. If an absolute path\n"
  71. " is not given, the default Asterisk sounds directory\n"
  72. " will be used.\n\n"
  73. " Example:\n"
  74. " file convert tt-weasels.gsm tt-weasels.ulaw\n";
  75. return NULL;
  76. case CLI_GENERATE:
  77. return NULL;
  78. }
  79. /* ugly, can be removed when CLI entries have ast_module pointers */
  80. ast_module_ref(ast_module_info->self);
  81. if (a->argc != 4 || ast_strlen_zero(a->argv[2]) || ast_strlen_zero(a->argv[3])) {
  82. ret = CLI_SHOWUSAGE;
  83. goto fail_out;
  84. }
  85. file_in = ast_strdupa(a->argv[2]);
  86. file_out = ast_strdupa(a->argv[3]);
  87. if (split_ext(file_in, &name_in, &ext_in)) {
  88. ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[2]);
  89. goto fail_out;
  90. }
  91. if (!(fs_in = ast_readfile(name_in, ext_in, NULL, O_RDONLY, 0, 0))) {
  92. ast_cli(a->fd, "Unable to open input file: %s\n", a->argv[2]);
  93. goto fail_out;
  94. }
  95. if (split_ext(file_out, &name_out, &ext_out)) {
  96. ast_cli(a->fd, "'%s' is an invalid filename!\n", a->argv[3]);
  97. goto fail_out;
  98. }
  99. if (!(fs_out = ast_writefile(name_out, ext_out, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
  100. ast_cli(a->fd, "Unable to open output file: %s\n", a->argv[3]);
  101. goto fail_out;
  102. }
  103. start = ast_tvnow();
  104. while ((f = ast_readframe(fs_in))) {
  105. if (ast_writestream(fs_out, f)) {
  106. ast_frfree(f);
  107. ast_cli(a->fd, "Failed to convert %s.%s to %s.%s!\n", name_in, ext_in, name_out, ext_out);
  108. goto fail_out;
  109. }
  110. ast_frfree(f);
  111. }
  112. cost = ast_tvdiff_ms(ast_tvnow(), start);
  113. ast_cli(a->fd, "Converted %s.%s to %s.%s in %dms\n", name_in, ext_in, name_out, ext_out, cost);
  114. ret = CLI_SUCCESS;
  115. fail_out:
  116. if (fs_out) {
  117. ast_closestream(fs_out);
  118. if (ret != CLI_SUCCESS)
  119. ast_filedelete(name_out, ext_out);
  120. }
  121. if (fs_in)
  122. ast_closestream(fs_in);
  123. ast_module_unref(ast_module_info->self);
  124. return ret;
  125. }
  126. static struct ast_cli_entry cli_convert[] = {
  127. AST_CLI_DEFINE(handle_cli_file_convert, "Convert audio file")
  128. };
  129. static int unload_module(void)
  130. {
  131. ast_cli_unregister_multiple(cli_convert, ARRAY_LEN(cli_convert));
  132. return 0;
  133. }
  134. static int load_module(void)
  135. {
  136. ast_cli_register_multiple(cli_convert, ARRAY_LEN(cli_convert));
  137. return AST_MODULE_LOAD_SUCCESS;
  138. }
  139. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "File format conversion CLI command");