mplayer 音轨 声道 切换
声道
mplayer -af channels=1:1
mplayer -af channels=1:1:1
音轨
#(就是shift+3)
声道
mplayer -af channels=1:1
mplayer -af channels=1:1:1
音轨
#(就是shift+3)
1. 起因
事情的起因是我准备用两个CDMA modem来拓展点对点连接的带宽,并且希望藉此实现两个modem之间的负载均衡。但是不幸的是,联通公司的接入设备不支持Multilink- PPP。于是,没有办法,我只好自己来实现负载均衡。实现负载均衡的办法有几种,网络上给出的一种办法是采用iproute2来完成包级别的负载均衡,这 是在内核一级实现的。但是我并不想把一切都交给内核去完成,我希望能够自己控制每一个modem上的流量。那么,我应该怎么办呢?
2. 解决方案
一开始,我想到的办法是创建两个套接口,然后将每个套接口都绑定到一 个本地IP地址上,我以为这样将会导致数据从所绑定的IP地址所在的网络设备上发出去。但是实践证明这种想法是错误的。因为每次在发送数据包之前,内核都 要查找路由表来决定从哪个网络接口上发送数据包。一旦找到一个合适的路由表项,就从该路由表项所指出的网络接口上将数据包发送出去。这样,就有一个问题, 由于路由表是高速缓存的,因此每次发送数据包之后,发送数据包的那个接口将会有更大的机会被内核再一次选中。在最坏的情况下,将导致一个modem忙得不 可开交,而另一个modem却“无人问津”。这显然违背了我的初衷。试验结果表明,当一个modem上发送了几百KB的数据之后,另外一个上仍然只发送了 几十个B。看来,此路不通!
循着上述思路,一种稍微令人错愕的做法是每次发送数据包之前,都先调 整路由表。调整路由表是很容易做到的。但是这样做的话也实在太麻烦了一点,所以,此想法也被我抛弃了。我甚至没有测试此法是否可行,但是从理论上来说是行 得通的。而且,在网上介绍的方法中,路由级别的负载均衡好像就是这样来实现的,不过,仅仅是好像而已,我并没有深究。
几番尝试未果之后,我把《UNIX网络编程》搬了出来,把UDP有关 的部分细细地筛了一遍。只发现了一个可能有作用的地方:可以通过setsockopt()设置一个套接口选项:SO_DONTROUTE,但是对该选项的 作用说得比较含糊。含糊归含糊,我还是实际尝试了一下,结果仍然是不行,原因未知。
于是,我不得不回到Linux本身,对着浩浩荡荡的一大堆man手册读起来。当我看到socket(7)的时候,忽然看到了一个令我眼前一亮的套接口选项:SO_BINDTODEVICE。从字面上看,这个选项应该就是我要的了。后来的试验结果证明事实的确如此。
在socket(7)中对该套接口选项的说明如下:
SO_BINDTODEVICE
Bind this socket to a particular device like "eth0", as specified in the passed interface name. If the name is an empty string or the option length is zero, the socket device binding is removed. The passed option is a variable-length null terminated interface name string with the maximum size of IFNAMSIZ. If a socket is bound to an interface, only packets received from that particular interface are processed by the socket. Note that this only works for some socket types, particularly AF_INET sockets. It is not supported for packet sockets (use normal bind(8) there).
这里,我是直接照搬过来的。不过,最后的那个bind(8)肯定是错 的,很显然应该是bind(2)才对。不管它,这不是我现在要解决的事情。这段话的中心意思是:当套接口被绑定到指定的网络设备接口之后,只有来自该设备 的数据包才会被套接口处理。那么,如果是套接口向外发送数据包呢?是否也只会从该网络接口发出呢?可恶的是,这里没有说。不过没关系,我们试验一下就知道 了。
一开始,我想当然地以为可以像下面这样:
char *dev = "ppp0";
int sock1 = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(sock1, SOL_SOCKET, SO_BINDTODEVICE, dev, sizeof(dev));
然而,实践再一次证明我想错了。但是我能有什么办法 呢,socket(7)中的说明写得就是这么晦涩,我看不出端倪来也是情有可原的。不过,有google在手,这点小问题我又何惧之有?于是google 之,很快就发现了问题的症结所在:在Linux下,对网络设备的引用都是通过struct ifreq来完成的。在netdevice(7)中对该结构体的说明如下:
struct ifreq {
char ifr_name[IFNAMSIZ];/* Interface name */
union {
struct sockaddrifr_addr;
struct sockaddrifr_dstaddr;
struct sockaddrifr_broadaddr;
struct sockaddrifr_netmask;
struct sockaddrifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmapifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
};
这里,我只需要ifr_name这个成员域就够了。代码修改成了下面这样:
struct ifreq if_ppp0;
struct ifreq if_ppp1;
strncpy(if_ppp0.ifr_name, "ppp0", IFNAMSIZ);
strncpy(if_ppp1.ifr_name, "ppp1", IFNAMSIZ);
sock1 = socket(AF_INET, SOCK_DGRAM, 0);
sock2 = socket(AF_INET, SOCK_DGRAM, 0);
if (setsockopt(sock1, SOL_SOCKET, SO_BINDTODEVICE,
(char *)&if_ppp0, sizeof(if_ppp0)) < 0) {
/*error handling*/
}
if (setsockopt(sock2, SOL_SOCKET, SO_BINDTODEVICE,
(char *)&if_ppp1, sizeof(if_ppp1)) < 0) {
/*error handling*/
}
然后,在程序的主体部分,每次在sock1上发送一个数据包,同时也 就会在sock2上发送一个数据包,并且程序中没有任何接收数据的动作。由于所有数据包的大小都是相等的。因此可以预计在两个网络接口上发送的数据量应该 相差不大才对。测试结果有力地支持了这一猜想:在运行程序一段时间后,接口ppp0上发送的数据量为702KB,而ppp1接口上发送的数据量为 895KB。虽然仍然相差了将近200KB,但是无论如何,比起原来的情况已经提高了不少。至于为什么会有这样200KB的差距,作者也正在找原因。
3. 更多结论
针对SO_BINDTODEVICE套接口选项,作者在全面阅读man手册之后,得出的结论如下:
(1) 对于TCP套接口、UDP套接口、RAW套接口,可以通过SO_BINDTODEVICE套接口选项将套接口绑定到指定的网络接口上。绑定之后,套接口的所有数据包收发都只经过指定的网络接口;
(2) 对于PACKET类型的套接口,不能通过SO_BINDTODEVICE绑定到指定的网络接口上,而要通过bind(2)来与特定的网络接口绑定,所用的 套接口地址结构为struct sockaddr_ll,此套接口地址结构是链路层的地址结构,独立于具体的网络设备。比如,该地址结构既可以用于表示PPP设备,也能用于表示 ethernet设备。
(3) SO_BINDTODEVICE套接口选项只适用于Linux系统。如果要编写运行在多操作系统平台上的程序,不能依赖SO_BINDTODEVICE来完成套接口与具体设备的绑定。
不过,作者并没有对TCP套接口和RAW套接口进行测试。对于PACKET套接口,上述结论是可信的,因为我阅读了dhcpd的源代码,发现对于PACKET套接口的确是通过bind(2)绑定到指定的网络接口上的
在chrome.exe 后添加--host-resolver-rules="MAP *.youtube.com 203.208.45.200,MAP *.ytimg.com 203.208.45.200,MAP *.googlevideo.com 203.208.45.200
#include <stdio.h>
#include <stdlib.h>
#define ARR_LEN 6
void buildBigHeap(int *arr, int s, int m); /* array,start_index,max_index */
void chg(int *arr, int one, int two);
int main(int argc, char *argv[])
{
int i;
int arr[ARR_LEN + 1] = { 0, 3, 23, 1, 433, 234, 134 };
/* first step,build big heap
* start at index arr_len/2,so its children
* will reach the end of arr */
for (i = ARR_LEN / 2; i > 0; i--) {
buildBigHeap(arr, i, ARR_LEN);
}
for (i = 1; i < ARR_LEN + 1; i++) {
printf("%d ", arr[i]);
printf("\n");
}
printf("==============\n");
/* exchange node 1(the biggest) and node last(the smallest)
* then rebuild big heap,so you put the biggest to end most
* ,then the second bigger to the second end most ... */
for (i = ARR_LEN; i > 0; i--) {
chg(arr, i, 1);
buildBigHeap(arr, 1, i - 1);
}
for (i = 1; i < ARR_LEN + 1; i++) {
printf("%d ", arr[i]);
printf("\n");
}
return 0;
}
void buildBigHeap(int *arr, int s, int m)
{
int i, tmp;
tmp = arr[s];
for (i = 2 * s; i <= m; i *= 2) {
if (i < m && arr[i] < arr[i + 1])
i++; /* i is the bigger child's index */
if (tmp > arr[i])
break; /* father is bigger than any child */
arr[s] = arr[i]; /* father get the bigger child's value */
s = i; /* not the end of story,begin again with the bigger child,who's value has been stolen by parent */
}
arr[s] = tmp;
}
void chg(int *arr, int one, int two)
{
int tmp;
tmp = arr[one];
arr[one] = arr[two];
arr[two] = tmp;
}
我的系统是用Windows 7 ,一直用的好好的Office2007,前天晚上打开Word想编辑一篇文章,突然发现office2007不能输入任何文字,在左下脚显示”不允许修 改,因为所选内容已被锁定”,卸载也卸不了,提示“安装无法继续因为一个必需文件已损坏或不可用”,直接用安装文件安装也提醒“安装无法继续因为一个必需 文件已损坏或不可用”,在百度搜发现原来是软件过期了,被微软给封了。
折腾了半天终于找到了解决方案,步骤如下:
一、打开http://support.microsoft.com/kb/290301,下载“Windows Installer 清理实用工具”;
二、下载下来安装好后运行,在里面删除所有的office2007组件;
三、用序列号 PGHBF-6K7PC-J9989-BGGJD-TKT3Q 重新安装Office2007;
四、然后重启,不要打开任何office程序,接下来验证用下面这个文件破解补丁:http://cid-54548d819b97ec2b.skydrive.live.com/embedicon.aspx/.Public/Tools/Office%202007%20%e5%85%a8%e7%b3%bb%e5%88%97%e6%bf%80%e6%b4%bb%e9%aa%8c%e8%af%81%e7%a0%b4%e8%a7%a3%e8%a1%a5%e4%b8%81.rar ,注意,补丁必须在Administrator帐号底下才能破解成功;
五、然后打开一个office程序在弹出的激活对话框中选择电话激活,国家一定要选美国,6位激活ID随便填(在输入每段的第6个字符时,会出现“ID错误”的提示,不用管它,单击确定继续填下一段)。单击下一步,激活成功!!再去验证显示为正版!
1.TR_NAME 修改
//#define TR_NAME "Transmission"
#define TR_NAME "uTorrent"
我看结果,好像是这个地方(抓包的User-Agent : uTorrent/3130 \r\n)
curl_easy_setopt( e, CURLOPT_USERAGENT, TR_NAME "/" SHORT_VERSION_STRING );
2.version.h(libtransmission/version.h)
#define PEERID_PREFIX "-TR2130-"
#define USERAGENT_PREFIX "2.13"
#define SVN_REVISION "11501"
#define SVN_REVISION_NUM 11501
#define SHORT_VERSION_STRING "2.13"
#define LONG_VERSION_STRING "2.13 (11501)"
#define VERSION_STRING_INFOPLIST 2.13
#define MAJOR_VERSION 2
#define MINOR_VERSION 13
#define TR_STABLE_RELEASE 1
/*-UT3130- 那个好像是peer-id的时候要*/
#define PEERID_PREFIX "-UT3130-"
#define USERAGENT_PREFIX "3130"
#define SVN_REVISION "26837"
#define SVN_REVISION_NUM 26837
#define SHORT_VERSION_STRING "3130"
#define LONG_VERSION_STRING "3130 (26837)"
#define VERSION_STRING_INFOPLIST 3130
#define MAJOR_VERSION 3130
#define MINOR_VERSION 0
#define TR_STABLE_RELEASE 1
3.more
announcer.c -->tr_announcerAddBytes-->byteCounts[type]
type == TR_ANN_DOWN
Did you ever come across this problem: mplayer plays some mkv files normally,but when playing other mkv files,mplayer gives you errors like:
[h264 @ 0xb6445900]AVC: nal size 171014
[h264 @ 0xb6445900]no frame!
Error while decoding frame!
[h264 @ 0xb6445900]AVC: nal size 27713
[h264 @ 0xb6445900]no frame!
Error while decoding frame!
Error while decoding frame![h264 @ 0xb6445900]AVC: nal size 4268801
[h264 @ 0xb6445900]no frame!
Error while decoding frame!Too many audio packets in the buffer: (4099 in 7337210 bytes).
if you use mediainfo to see info of these files,you will notice this line :
Muxing mode : Header stripping
In order to reduce file size , mkvmerge did some tricks,which makes mplayer go into mess.
To solve this problem,just
mplayer -demuxer lavf file_name.mkv
referenced:
放入~/.bashrc
function xcd ()
{
declare -a names
i=0
FILE_DIRS="/dev/shm/fuck_dirs"
ls -1 -F | grep [/$] | awk -F'/' '{print $1}' > $FILE_DIRS
while read dirname
do
names[$i]=$dirname
let "i+=1"
done < $FILE_DIRS
rm $FILE_DIRS
dir_nums=${#names[@]}
if [ $dir_nums -eq 0 ]
then
echo
echo " There is no directory,bye!"
echo
return
fi
echo
echo " index directory"
echo
for((i=0;i<$dir_nums;i++))
do
echo " $i ${names[$i]}"
done
echo
read -p " Now,give me the index : " choosed_idx
echo
if [[ $choosed_idx -ge $dir_nums || $choosed_idx -lt 0 ]]
then
echo " Are you kidding me?"
echo
return
else
echo " Any question,Email me:40964654306938118710083764053554616036618"
cd "${names[$choosed_idx]}"
echo
fi
}
refrenced :
change-current-directory-from-a-script
Bash中如何退出当前函数而不退出整个脚本
linux命令:ls命令只列出文件名不列出目录名的正确方法