LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1893|回复: 12

[交流]使用mplayer定时录制网络广播

[复制链接]
发表于 2007-12-10 16:40:45 | 显示全部楼层 |阅读模式
初次写这么“复杂”的脚本,请大家多多指教。
使用这个脚本,配合at或cron可以实现定时段录制网络广播(电视),并且可以避免网络不畅引起的mplayer意外退出,和其他意外中断的情况。
  1. # !/bin/bash
  2. # 参数1:录制时长。
  3. # 重新启动mplayer的函数。
  4. restartencode(){
  5.         echo "restart程序启动"
  6.         # 侦测现在的mplayer 的pid
  7.         mplayerpid_now=`ps -af | grep mplayer | grep cnr9 | awk '{ print $2 }'`
  8.         echo "原mplayer的pid : $1"
  9.         echo "现mplayer的pid : $mplayerpid_now"
  10.         mplayerpid=$mplayerpid_now
  11.         # 首先测试是否超过最大重试次数,然后测试是否有mplayer正在运行。
  12.         if [ "$try_times" -lt "try_limit" ]
  13.                 then
  14.                         if [ "$mplayerpid_now" ]
  15.                                 then
  16.                                         echo "不需重启mplayer"
  17.                                 else
  18.                                         audiofile="cnr9-$(date +'%Y%m%d-%T').rm.avi"
  19.                                         echo "重新启动mplayer"
  20.                                         mplayer $address -dumpstream -dumpfile ~/audio/$audiofile < /dev/null > /dev/null 2>&1 &
  21.                                         mplayerpid=$!
  22.                                         echo "新mplayer的pid : $mplayerpid"
  23.                                         let "try_times += 1"
  24.                                         echo "重试次数$try_times"
  25.                         fi
  26.                 else
  27.                         echo "超出重试次数退出!"
  28.                         exit
  29.         fi
  30.         }
  31. # 录制时长
  32. runtime=${1:-30m}
  33. # 这个脚本的pid
  34. mypid=$$
  35. # Enable immediate notification of SIGCHLD
  36. set -bm
  37. # 录制文件名,文件名为“基名+时间”以免产生覆盖
  38. audiofile="cnr9-$(date +'%Y%m%d-%T').rm.avi"
  39. # 录制地址
  40. address="rtsp://211.89.225.1:554/encoder/cnr9"
  41. # mplayer缓冲cache设置,单位K
  42. cache=32
  43. # 网络连接重试次数
  44. try_times=0
  45. # 网络连接次数限定
  46. try_limit=10
  47. # 屏幕显示
  48. echo "开始录制: $audiofile"
  49. echo "开始时间: $(date +'%Y%m%d-%T')"
  50. echo "录制时长: $1 "
  51. echo "录制地址: $address"
  52. echo "mplayer缓冲cache设置:$cache K"
  53. echo "======================================="
  54. # 利用mplayer进行录制,注意mplayer放入后台的用法。
  55. mplayer -cache $cache $address -dumpstream -dumpfile ~/audio/$audiofile < /dev/null > /dev/null 2>&1 &
  56. echo "mplayer -cache $cache $address -dumpstream -dumpfile $audiofile < /dev/null 2>&1 &"
  57. echo "======================================="
  58. # mplayer的pid
  59. mplayerpid=$!
  60. echo "初始mplayer的pid:$mplayerpid"
  61. # mplayer在录制时长结束前退出,可能是网络问题。利用trap侦测信号,调用restart函数重启mplayer。
  62. # Set a trap
  63. trap "echo 'mplayer错误,重试,已经重试$try_times'" CHLD INT TERM KILL QUIT EXIT
  64. trap "restartencode $mplayerpid" CHLD INT TERM KILL QUIT EXIT
  65. # 开始计算录制时长前的缓冲时间,mplayer录制缓冲时间
  66. sleep 10s
  67. # Sleep for the specified time,录制持续时间控制。
  68. sleep $runtime
  69. sleeppid=$!
  70. # Disable traps,trap复位
  71. trap SIGCHLD
  72. trap SIGINT
  73. trap SIGTERM
  74. trap SIGKILL
  75. trap SIGQUIT
  76. trap EXIT
  77. trap TSTP
  78. # 录制结束
  79. mplayerpid_now=`ps -a | grep mplayer | awk '{ print $1 }'`
  80. echo "现在mplayer进程$mplayerpid_now"
  81. echo "中止mplayer进程$mplayerpid"
  82. kill -15 $mplayerpid
  83. echo "录制完成!"
复制代码
 楼主| 发表于 2007-12-10 20:07:16 | 显示全部楼层
稍微改了一下:
  1. # !/bin/bash

  2. # 参数1:录制时长。参数2:选择要录制的频道(网址)。

  3. # 频道(网址)选择函数
  4. channel_url(){
  5.         case $1 in
  6.                 [1]        )        address="rtsp://211.89.225.1:554/encoder/cnr9"
  7.                                 audiofile_base="cnr9" ;;
  8.                 [2]        )        address="mms://alive.bjradio.com.cn/fm876"
  9.                                 audiofile_base="fm876" ;;
  10.                 *        )        echo "第二个参数不正确!退出!"
  11.                                 exit ;;
  12.         esac
  13.         }

  14. # 重新启动mplayer的函数。
  15. restartencode(){
  16.         echo "restart程序启动"
  17.         # 侦测现在的mplayer 的pid
  18.         mplayerpid_now=`ps -af | grep mplayer | grep $audiofile_base | awk '{ print $2 }'`
  19.         echo "原mplayer的pid : $1"
  20.         echo "现mplayer的pid : $mplayerpid_now"
  21.         mplayerpid=$mplayerpid_now
  22.         # 首先测试是否超过最大重试次数,然后测试是否有mplayer正在运行。
  23.         if [[ "$try_times" -lt "try_limit" ]]
  24.                 then
  25.                         if [[ "$mplayerpid_now" ]]
  26.                                 then
  27.                                         echo "不需重启mplayer"
  28.                                 else
  29.                                         audiofile="$audiofile_base-$(date +'%Y%m%d-%T').avi"
  30.                                         echo "重新启动mplayer"
  31.                                         mplayer $address -dumpstream -dumpfile ~/audio/$audiofile < /dev/null > /dev/null 2>&1 &
  32.                                         mplayerpid=$!
  33.                                         echo "新mplayer的pid : $mplayerpid"
  34.                                         let "try_times += 1"
  35.                                         echo "重试次数$try_times"
  36.                         fi
  37.                 else
  38.                         echo "超出重试次数退出!"
  39.                         exit
  40.         fi
  41.         }

  42. channel_url $2
  43. # 录制时长
  44. runtime=${1:-30m}
  45. # Enable immediate notification of SIGCHLD
  46. set -bm
  47. # 录制文件名,文件名为“基名+时间”以免产生覆盖,统一使用avi“容器”
  48. audiofile="$audiofile_base-$(date +'%Y%m%d-%T').avi"
  49. # mplayer缓冲cache设置,单位K
  50. cache=32
  51. # 网络连接重试次数
  52. try_times=0
  53. # 网络连接次数限定
  54. try_limit=10

  55. # 屏幕显示
  56. echo "开始录制: $audiofile"
  57. echo "开始时间: $(date +'%Y%m%d-%T')"
  58. echo "录制时长: $1 "
  59. echo "录制地址: $address"
  60. echo "mplayer缓冲cache设置:$cache K"
  61. echo "======================================="

  62. # 利用mplayer进行录制,注意mplayer放入后台的用法。
  63. mplayer -cache $cache $address -dumpstream -dumpfile ~/audio/$audiofile < /dev/null > /dev/null 2>&1 &

  64. echo "mplayer -cache $cache $address -dumpstream -dumpfile $audiofile < /dev/null 2>&1 &"
  65. echo "======================================="

  66. # mplayer的pid
  67. mplayerpid=$!
  68. echo "初始mplayer的pid:$mplayerpid"

  69. # mplayer在录制时长结束前退出,可能是网络问题。利用trap侦测信号,调用restart函数重启mplayer。
  70. trap "restartencode $mplayerpid" CHLD INT TERM KILL QUIT EXIT

  71. # 开始计算录制时长前的缓冲时间,mplayer录制缓冲时间
  72. sleep 10s
  73. # Sleep for the specified time,录制持续时间控制。
  74. sleep $runtime
  75. sleeppid=$!

  76. # Disable traps,trap复位
  77. trap SIGCHLD
  78. trap SIGINT
  79. trap SIGTERM
  80. trap SIGKILL
  81. trap SIGQUIT
  82. trap EXIT
  83. trap TSTP

  84. # 录制结束
  85. mplayerpid_now=`ps -af | grep mplayer | grep $audiofile_base | awk '{ print $2 }'`
  86. echo "现在mplayer进程$mplayerpid_now"
  87. echo "中止mplayer进程$mplayerpid_now"
  88. kill -15 $mplayerpid_now
  89. echo "录制完成!"
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-12-10 21:01:34 | 显示全部楼层
关于查找进程id的方法并不正确,应该是
ps -a|grep mplayer|grep -v grep
如果按你的写法可能会包括grep mplayer这个进程。
可以把trap的那句话改成
trap 'restartencode $mplayerpid' CHLD INT TERM KILL QUIT EXIT
如果用"的话,每次调用restartencode都用是相同的参数,不知道楼主的
本意是什么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-10 23:02:01 | 显示全部楼层
查找id应该是这个:
mplayerpid_now=`ps -af | grep mplayer | grep $audiofile_base | awk '{ print $2 }'`

原来向restart函数传递参数是要做比较用的,不过现在不传递参数也是可以的,亦即现在传递这个参数实属多余。
但是我认为双引号中的$mplayerpid也是变化的。
回复 支持 反对

使用道具 举报

发表于 2007-12-10 23:08:17 | 显示全部楼层
这样查找进程id就不会有什么问题了。
回复 支持 反对

使用道具 举报

发表于 2007-12-11 09:00:04 | 显示全部楼层
不错的脚本, 收了.

另外想起了以前写过的一个查找进程的代码, 虽然这里用不到, 不过还是帖一下, 对比 ocean390 兄在 3 楼提供的方法可以少一层管道, 也算是个技巧吧
  1. ps -af | grep [m]player
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-11 21:09:11 | 显示全部楼层
有个问题:
当我如下运行时
  1. $ ./encode_audio.sh 10s 1 &
复制代码
会使控制台退出。
但我把
  1. encode_audio.sh 10s 1 &
复制代码
放入一个文件中,例如脚本encode_cnr9.sh中,然后执行这个脚本则没有问题。
回复 支持 反对

使用道具 举报

发表于 2007-12-12 23:07:27 | 显示全部楼层
在文件的开头添加exec 2>/dev/null
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-12-13 22:27:14 | 显示全部楼层
Post by ocean390;1794944
在文件的开头添加exec 2>/dev/null

谢谢ocean390!
请问,为什么会有这样的现象呢?
回复 支持 反对

使用道具 举报

发表于 2007-12-13 22:36:51 | 显示全部楼层
我用这个程序为什么不能录制网络广播呢,难道你的是局域网内的服务器
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表