Archive for the ‘编程资料’ Category

PHP获取客户浏览器版本 系统版本 IP地址和IP所在国家源代码及例程

星期一, 八月 8th, 2016

原创内容,转载请注明出处: http://www.myzhenai.com.cn/post/2242.html http://www.myzhenai.com/thread-17902-1-1.html
关键字: php怎样获取客户浏览器 php怎样获取客户系统 php如何获取用户IP所在国家 php如何获取用户IP所在位置
演示地址: http://www.myzhenai.com.cn http://jiayu.mybabya.com/ http://tz.mybabya.com/ua.php
其实获取用户浏览器版本和系统版本都是根据用户浏览时提交的user agent信息来判断的, 对于用户的系统可以精确一些,但一些Linux系统还是无法作到获取精确的派生版本, 浏览器的获取就要难一些, 因为不同的浏览器,不同的版本的用户的user agent信息也都是不一样的. 这个只能是自己根据不同的需要进行修改. 这些图片是我在网络上收集并修改的.
一: 在源码目录中的functions.php文件中插入以下代码

/**
 * This is a small tool to obtain the user's browser to browse the system name and user name and address
 * Autor: RucLinux
 * Web: http://www.myzhenai.com.cn/ http://www.myzhenai.com/ http://www.haikou-china.com/ http://jiayu.mybabya.com/ http://www.0898-shop.com/
 */

/**
这是获取当前用户IP
 */

function get_ip() {
    $ip = $_SERVER["REMOTE_ADDR"]; /* 获取当前浏览用户地址,显示的是纯ip地址格式   */
    return $ip;
}

/**
这是获取当前用户IP所在位置
 */
function get_ip_address() {
    $chinaz = "http://www.baidu.com/baidu?wd="; /* 指定站长工具获取IP地址的页面地址,后边加上IP就可以了   */
    $ip = $_SERVER["REMOTE_ADDR"]; /* 获取当前浏览用户地址,显示的是纯ip地址格式   */
    $Source = file_get_contents($chinaz.$ip);  /* 获取网页源码,变量 $Source 即是当前IP地址的网页源码 */

    if ($Source !== ""){
        $aLeft = "$ip"; /* 第一次搜索的参数变量,第一次以这个为搜索条件,从这个变量开始搜索  */
        $aRight = ""; /* 第一次搜索的参数变量,搜索到这个变量就停止搜索,截取这中间的字符窜  */
        $Left = strpos($Source,$aLeft,0); /* 左边位置 */
        $Right = strpos($Source,$aRight,0); /* 右边位置 */
        $txit = substr($Source,$Left,$Right); /* 截取部份文本代码,第一个参数是要处理的字符窜,第二个参数是开始位置,第三个参数是结束位置 [第一次查询]*/
        $Left = strpos($txit,$aLeft,0); /* 左边位置 */
        $Right = strpos($txit,$aRight,0); /* 右边位置 */
        $txit = substr($txit,0,$Right); /* 截取部份文本代码,第一个参数是要处理的字符窜,第二个参数是开始位置,第三个参数是结束位置 [第二次查询]*/
        $txit = substr($txit,20); /* 截取部份文本代码,第一个参数是要处理的字符窜,第二个参数是开始位置, [第三次查询]*/
        $txit = str_replace(">","",$txit); /* 替换字符 */
        return $txit;
    }
}


/**
将所处国家代码转换为中文的国家名称
 */
function transCode($code) {
    $ind=array('AA'=>'阿鲁巴',
        'AD'=>'安道尔',
        'AE'=>'阿联酋',
        'AF'=>'阿富汗',
        'AG'=>'安提瓜和巴布达',
        'AL'=>'阿尔巴尼亚',
        'AM'=>'亚美尼亚',
        'AN'=>'荷属安德列斯',
        'AO'=>'安哥拉',
        'AQ'=>'南极洲',
        'AR'=>'阿根廷',
        'AS'=>'东萨摩亚',
        'AT'=>'奥地利',
        'AU'=>'澳大利亚',
        'AZ'=>'阿塞拜疆',
        'Av'=>'安圭拉岛',
        'BA'=>'波黑',
        'BB'=>'巴巴多斯',
        'BD'=>'孟加拉',
        'BE'=>'比利时',
        'BF'=>'巴哈马',
        'BF'=>'布基纳法索',
        'BG'=>'保加利亚',
        'BH'=>'巴林',
        'BI'=>'布隆迪',
        'BJ'=>'贝宁',
        'BM'=>'百慕大',
        'BN'=>'文莱布鲁萨兰',
        'BO'=>'玻利维亚',
        'BR'=>'巴西',
        'BS'=>'巴哈马',
        'BT'=>'不丹',
        'BV'=>'布韦岛',
        'BW'=>'博茨瓦纳',
        'BY'=>'白俄罗斯',
        'BZ'=>'伯里兹',
        'CA'=>'加拿大',
        'CB'=>'柬埔寨',
        'CC'=>'可可斯群岛',
        'CD'=>'刚果',
        'CF'=>'中非',
        'CG'=>'刚果',
        'CH'=>'瑞士',
        'CI'=>'象牙海岸',
        'CK'=>'库克群岛',
        'CL'=>'智利',
        'CM'=>'喀麦隆',
        'CN'=>'中国',
        'CO'=>'哥伦比亚',
        'CR'=>'哥斯达黎加',
        'CS'=>'捷克斯洛伐克',
        'CU'=>'古巴',
        'CV'=>'佛得角',
        'CX'=>'圣诞岛',
        'CY'=>'塞普路斯',
        'CZ'=>'捷克',
        'DE'=>'德国',
        'DJ'=>'吉布提',
        'DK'=>'丹麦',
        'DM'=>'多米尼加共和国',
        'DO'=>'多米尼加联邦',
        'DZ'=>'阿尔及利亚',
        'EC'=>'厄瓜多尔',
        'EE'=>'爱沙尼亚',
        'EG'=>'埃及',
        'EH'=>'西撒哈拉',
        'ER'=>'厄立特里亚',
        'ES'=>'西班牙',
        'ET'=>'埃塞俄比亚',
        'FI'=>'芬兰',
        'FJ'=>'斐济',
        'FK'=>'福兰克群岛',
        'FM'=>'米克罗尼西亚',
        'FO'=>'法罗群岛',
        'FR'=>'法国',
        'FX'=>'法国-主教区',
        'GA'=>'加蓬',
        'GB'=>'英国',
        'GD'=>'格林纳达',
        'GE'=>'格鲁吉亚',
        'GF'=>'法属圭亚那',
        'GH'=>'加纳',
        'GI'=>'直布罗陀',
        'GL'=>'格陵兰岛',
        'GM'=>'冈比亚',
        'GN'=>'几内亚',
        'GP'=>'法属德洛普群岛',
        'GQ'=>'赤道几内亚',
        'GR'=>'希腊',
        'GS'=>'S. Georgia and S. Sandwich Isls.',
        'GT'=>'危地马拉',
        'GU'=>'关岛',
        'GW'=>'几内亚比绍',
        'GY'=>'圭亚那',
        'HK'=>'中国香港特区',
        'HM'=>'赫德和麦克唐纳群岛',
        'HN'=>'洪都拉斯',
        'HR'=>'克罗地亚',
        'HT'=>'海地',
        'HU'=>'匈牙利',
        'ID'=>'印度尼西亚',
        'IE'=>'爱尔兰',
        'IL'=>'以色列',
        'IN'=>'印度',
        'IO'=>'英属印度洋领地',
        'IQ'=>'伊拉克',
        'IR'=>'伊朗',
        'IS'=>'冰岛',
        'IT'=>'意大利',
        'JM'=>'牙买加',
        'JO'=>'约旦',
        'JP'=>'日本',
        'KE'=>'肯尼亚',
        'KG'=>'吉尔吉斯斯坦',
        'KH'=>'柬埔寨',
        'KI'=>'基里巴斯',
        'KM'=>'科摩罗',
        'KN'=>'圣基茨和尼维斯',
        'KP'=>'韩国',
        'KR'=>'朝鲜',
        'KW'=>'科威特',
        'KY'=>'开曼群岛',
        'KZ'=>'哈萨克斯坦',
        'LA'=>'老挝',
        'LB'=>'黎巴嫩',
        'LC'=>'圣卢西亚',
        'LI'=>'列支顿士登',
        'LK'=>'斯里兰卡',
        'LR'=>'利比里亚',
        'LS'=>'莱索托',
        'LT'=>'立陶宛',
        'LU'=>'卢森堡',
        'LV'=>'拉托维亚',
        'LY'=>'利比亚',
        'MA'=>'摩洛哥',
        'MC'=>'摩纳哥',
        'MD'=>'摩尔多瓦',
        'MG'=>'马达加斯加',
        'MH'=>'马绍尔群岛',
        'MK'=>'马其顿',
        'ML'=>'马里',
        'MM'=>'缅甸',
        'MN'=>'蒙古',
        'MO'=>'中国澳门特区',
        'MP'=>'北马里亚纳群岛',
        'MQ'=>'法属马提尼克群岛',
        'MR'=>'毛里塔尼亚',
        'MS'=>'蒙塞拉特岛',
        'MT'=>'马耳他',
        'MU'=>'毛里求斯',
        'MV'=>'马尔代夫',
        'MW'=>'马拉维',
        'MX'=>'墨西哥',
        'MY'=>'马来西亚',
        'MZ'=>'莫桑比克',
        'NA'=>'纳米比亚',
        'NC'=>'新卡里多尼亚',
        'NE'=>'尼日尔',
        'NF'=>'诺福克岛',
        'NG'=>'尼日利亚',
        'NI'=>'尼加拉瓜',
        'NL'=>'荷兰',
        'NO'=>'挪威',
        'NP'=>'尼泊尔',
        'NR'=>'瑙鲁',
        'NT'=>'中立区(沙特-伊拉克间)',
        'NU'=>'纽爱',
        'NZ'=>'新西兰',
        'OM'=>'阿曼',
        'PA'=>'巴拿马',
        'PE'=>'秘鲁',
        'PF'=>'法属玻里尼西亚',
        'PG'=>'巴布亚新几内亚',
        'PH'=>'菲律宾',
        'PK'=>'巴基斯坦',
        'PL'=>'波兰',
        'PM'=>'圣皮艾尔和密克隆群岛',
        'PN'=>'皮特克恩岛',
        'PR'=>'波多黎各',
        'PT'=>'葡萄牙',
        'PW'=>'帕劳',
        'PY'=>'巴拉圭',
        'QA'=>'卡塔尔',
        'RE'=>'法属尼留旺岛',
        'RO'=>'罗马尼亚',
        'RU'=>'俄罗斯',
        'RW'=>'卢旺达',
        'SA'=>'沙特阿拉伯',
        'SC'=>'塞舌尔',
        'SD'=>'苏丹',
        'SE'=>'瑞典',
        'SG'=>'新加坡',
        'SH'=>'圣赫勒拿',
        'SI'=>'斯罗文尼亚',
        'SJ'=>'斯瓦尔巴特和扬马延岛',
        'SK'=>'斯洛伐克',
        'SL'=>'塞拉利昂',
        'SM'=>'圣马力诺',
        'SN'=>'塞内加尔',
        'SO'=>'索马里',
        'SR'=>'苏里南',
        'ST'=>'圣多美和普林西比',
        'SU'=>'前苏联',
        'SV'=>'萨尔瓦多',
        'SY'=>'叙利亚',
        'SZ'=>'斯威士兰',
        'Sb'=>'所罗门群岛',
        'TC'=>'特克斯和凯科斯群岛',
        'TD'=>'乍得',
        'TF'=>'法国南部领地',
        'TG'=>'多哥',
        'TH'=>'泰国',
        'TJ'=>'塔吉克斯坦',
        'TK'=>'托克劳群岛',
        'TM'=>'土库曼斯坦',
        'TN'=>'突尼斯',
        'TO'=>'汤加',
        'TP'=>'东帝汶',
        'TR'=>'土尔其',
        'TT'=>'特立尼达和多巴哥',
        'TV'=>'图瓦卢',
        'TW'=>'中国台湾省',
        'TZ'=>'坦桑尼亚',
        'UA'=>'乌克兰',
        'UG'=>'乌干达',
        'UK'=>'英国',
        'UM'=>'美国海外领地',
        'US'=>'美国',
        'UY'=>'乌拉圭',
        'UZ'=>'乌兹别克斯坦',
        'VA'=>'梵蒂岗',
        'VC'=>'圣文森特和格陵纳丁斯',
        'VE'=>'委内瑞拉',
        'VG'=>'英属维京群岛',
        'VI'=>'美属维京群岛',
        'VN'=>'越南',
        'VU'=>'瓦努阿鲁',
        'WF'=>'瓦里斯和福图纳群岛',
        'WS'=>'西萨摩亚',
        'YE'=>'也门',
        'YT'=>'马约特岛',
        'YU'=>'南斯拉夫',
        'ZA'=>'南非',
        'ZM'=>'赞比亚',
        'ZR'=>'扎伊尔',
        'ZW'=>'津巴布韦');
    $code=strtoupper($code);
    $name= isset($ind[$code]) ? $ind[$code] : '局域网';
    if (empty($name)) {
        return null;
    }
    return $name;
}

/**
这是获取当前用户IP所在国家
 */
function get_ip_nation() {
    $ip = $_SERVER["REMOTE_ADDR"]; /* 获取当前浏览用户地址,显示的是纯ip地址格式   */
    $nat = "http://www.geoplugin.net/json.gp?ip="; /* 从指定的网站那里获得IP所处位置的信息 */
    $Source = file_get_contents($nat.$ip);  /* 获取网页源码,变量 $Source 即是当前IP地址的网页源码 */
    $area = json_decode($Source);
    return transCode($area->geoplugin_countryCode);
}


/**
这是输出当前用户IP所在国家或地区的旗帜
 */
function outputflag() {
    $ip = $_SERVER["REMOTE_ADDR"]; /* 获取当前浏览用户地址,显示的是纯ip地址格式   */
    $nat = "http://www.geoplugin.net/json.gp?ip="; /* 从指定的网站那里获得IP所处位置的信息 */
    $Source = file_get_contents($nat.$ip);  /* 获取网页源码,变量 $Source 即是当前IP地址的网页源码 */
    $area = json_decode($Source);
    $ad = get_stylesheet_directory_uri(); /* 获取当前主题目录路径 这个变量是wordpress对有的 */
    $userarea = transCode($area->geoplugin_countryCode);
        $flag = strtolower($area->geoplugin_countryCode); /* 将字符窜数据转换成小写 */
        if ($flag == "tw" || $flag == "hk" || $flag == "mo" ) {
        $version = "<img src=\"$ad/images/nation/cn.png\" alt=\"中华人民共和国\" title=\"中华人民共和国\" width=\"16\" /> || <img src=\"$ad/images/nation/$flag.png\" alt=\"$userarea\" title=\"$userarea\" width=\"16\" /> "; /** 定义图片地址 */
         }else{
        $version = "<img src=\"$ad/images/nation/$flag.png\" alt=\"$userarea\" title=\"$userarea\" width=\"16\" />"; /** 定义图片地址 */
         }
         return $version;
         }

/**
这是获取当前用户浏览器UserAgent数据中的真正的系统名称或浏览器名称
 */
function get_pickup_browser() {
    $agent = $_SERVER['HTTP_USER_AGENT']; /** 获取用户当前UserAgent数据  */
    $im = strtolower($agent); /* 将字符窜数据转换成小写 */
    $mb = array(); /** 创建一个空白数组 */
        if (strpos($im,"firefox")){
            array_push($mb,strpos($im,"firefox"),"firefox"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"opera")){
            array_push($mb,strpos($im,"opera"),"opera"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"chrome")){
            array_push($mb,strpos($im,"chrome"),"chrome"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"safari")){
            array_push($mb,strpos($im,"safari"),"safari"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"edge/")){
            array_push($mb,strpos($im,"edge/"),"edge"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"maxthon")){
            array_push($mb,strpos($im,"maxthon"),"maxthon"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"tencenttraveler")){
            array_push($mb,strpos($im,"tencenttraveler"),"tencenttraveler"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"world")){
            array_push($mb,strpos($im,"world"),"world"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"360se")){
            array_push($mb,strpos($im,"360se"),"360se"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"metasr")){
            array_push($mb,strpos($im,"metasr"),"metasr"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"baidu")){
            array_push($mb,strpos($im,"baidu"),"baidu"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"qq")){
            array_push($mb,strpos($im,"qq"),"qq"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"360ee")){
            array_push($mb,strpos($im,"360ee"),"360ee"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"lbbrowser")){
            array_push($mb,strpos($im,"lbbrowser"),"lbbrowser"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"ucbrowser")){
            array_push($mb,strpos($im,"ucbrowser"),"ucbrowser"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"lceweasel")){
            array_push($mb,strpos($im,"lceweasel"),"lceweasel"); /** 加入一条数组信息并覆值 */
        }
        if (count($mb) >= 2){
        $mb = array_flip(array_flip($mb)); /** 去除重复的数组数据 */
            $b = end($mb); /** 取数组里最大的元素的值  */
        }
        unset($mb);
        return $b;
        } /** get_pickup_browser */

function get_pickup_os() {
    $agent = $_SERVER['HTTP_USER_AGENT']; /** 获取用户当前UserAgent数据  */
    $im = strtolower($agent); /* 将字符窜数据转换成小写 */
    $mb = array(); /** 创建一个空白数组 */
        if (strpos($im,"linux")){
            array_push($mb,strpos($im,"linux"),"linux"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"centos")){
            array_push($mb,strpos($im,"centos"),"centos"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"debian")){
            array_push($mb,strpos($im,"debian"),"debian"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"ubuntu")){
            array_push($mb,strpos($im,"ubuntu"),"ubuntu"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"fedora")){
            array_push($mb,strpos($im,"fedora"),"fedora"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"gentoo")){
            array_push($mb,strpos($im,"gentoo"),"gentoo"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"unix")){
            array_push($mb,strpos($im,"unix"),"unix"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"mac")){
            array_push($mb,strpos($im,"mac"),"mac"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"sun")){
            array_push($mb,strpos($im,"sun"),"sun"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"ibm")){
            array_push($mb,strpos($im,"firefox"),"firefox"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"android")){
            array_push($mb,strpos($im,"android"),"android"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"ipad")){
            array_push($mb,strpos($im,"ipad"),"ipad"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"iphone")){
            array_push($mb,strpos($im,"iphone"),"iphone"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"netbsd")){
            array_push($mb,strpos($im,"netbsd"),"netbsd"); /** 加入一条数组信息并覆值 */
        }
        if (strpos($im,"freebsd")){
            array_push($mb,strpos($im,"freebsd"),"freebsd"); /** 加入一条数组信息并覆值 */
        }
        if (count($mb) >= 1){
            $b = end($mb); /** 取数组里最大的元素的值  */
        }
        unset($mb);
        return $b;
        } /** get_pickup_os */


/**
这是获取当前用户浏览器名称和图片或者是当前用户系统的名称和图片
 */
function get_browser_name() {
    $agent = $_SERVER['HTTP_USER_AGENT']; /** 获取用户当前UserAgent数据  */
    $im = strtolower($agent); /* 将字符窜数据转换成小写 */
    $ad = get_stylesheet_directory_uri(); /* 获取当前主题目录路径  */
    $t = get_pickup_browser();
    if ($t == "firefox"){
        $t = "FireFix火狐浏览器";
        $version = "<img src=\"$ad/images/browser/firefox.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "opera"){
        $t = "Opera浏览器";
        $version = "<img src=\"$ad/images/browser/opera.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "chrome"){
        $t = "Chrome浏览器";
        $version = "<img src=\"$ad/images/browser/chrome.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "safari"){
        $t = "Safari浏览器";
        $version = "<img src=\"$ad/images/browser/safari.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"msie 9.0")){
        $t = "Internet Explorer 9.0浏览器";
        $version = "<img src=\"$ad/images/browser/ie.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"msie 8.0")){
        $t = "Internet Explorer 8.0浏览器";
        $version = "<img src=\"/images/browser/ie.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"msie 7.0")){
        $t = "Internet Explorer 7.0浏览器";
        $version = "<img src=\"$ad/images/browser/ie.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"msie 6.0")){
        $t = "Internet Explorer 6.0浏览器";
        $version = "<img src=\"$ad/images/browser/ie.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "edge"){
        $t = "Edge浏览器";
        $version = "<img src=\"$ad/images/browser/edge.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "maxthon"){
        $t = "傲游浏览器";
        $version = "<img src=\"$ad/images/browser/maxthon.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "tencenttraveler"){
        $t = "腾讯TT浏览器";
        $version = "<img src=\"$ad/images/browser/tt.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "world"){
        $t = "世界之窗浏览器";
        $version = "<img src=\"$ad/images/browser/world.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "360se"){
        $t = "360浏览器";
        $version = "<img src=\"$ad/images/browser/360.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "metasr"){
        $t = "搜狗浏览器";
        $version = "<img src=\"$ad/images/browser/metasr.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "baidu"){
        $t = "百度浏览器";
        $version = "<img src=\"$ad/images/browser/baidu.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "qq"){
        $t = "QQ浏览器";
        $version = "<img src=\"$ad/images/browser/qq.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "360ee"){
        $t = "360极速浏览器";
        $version = "<img src=\"$ad/images/browser/360ee.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "lbbrowser"){
        $t = "猎豹浏览器";
        $version = "<img src=\"$ad/images/browser/lb.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "ucbrowser"){
        $t = "UC浏览器";
        $version = "<img src=\"$ad/images/browser/uc.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"rv:11.0")){
        $t = "Internet Explorer 11浏览器";
        $version = "<img src=\"$ad/images/browser/ie.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "lceweasel"){
        $t = "lceweasel浏览器";
        $version = "<img src=\"$ad/images/browser/lceweasel.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    return $version;
}

/**
这是获取当前用户系统的名称和图片
 */

function get_os(){
    /** 以下是系统信息 */
    $agent = $_SERVER['HTTP_USER_AGENT']; /** 获取用户当前UserAgent数据  */
    $im = strtolower($agent); /* 将字符窜数据转换成小写 */
    $ad = get_stylesheet_directory_uri(); /* 获取当前主题目录路径  */
    $t = get_pickup_os();
    if (strpos($im,"win") && strpos($im, '95')){
        $t = "Windows 95系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win 9x") && strpos($im, '4.90')){
        $t = "Windows ME系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"98")){
        $t = "Windows 98系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 5.1")){
        $t = "Windows XP系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 5.2")){
        $t = "Windows  Server 2003系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 5.3")){
        $t = "Windows 2000系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 6.0")){
        $t = "Windows Vista/Windows Server 2008系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 6.1")){
        $t = "Windows 7/Windows Server 2008 R2系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 6.2")){
        $t = "Windows 8/Windows Server 2012系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"win") && strpos($im,"nt 10")){
        $t = "Windows 10系统";
        $version = "<img src=\"$ad/images/system/wind.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "linux"){
        $t = "Linux系统";
        $version = "<img src=\"$ad/images/system/linux.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "unix"){
        $t = "Unix系统";
        $version = "<img src=\"$ad/images/system/unix.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"sun") && strpos($im,"os")){
        $t = "SunOS系统";
        $version = "<img src=\"$ad/images/system/sun.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if (strpos($im,"ibm") && strpos($im,"os")){
        $t = "IBM系统";
        $version = "<img src=\"$ad/images/system/ibm.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "mac"){
        $t = "Mac系统";
        $version = "<img src=\"$ad/images/system/mac.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "android"){
        $t = "安卓系统";
        $version = "<img src=\"$ad/images/system/android.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "ipad"){
        $t = "IPAD系统";
        $version = "<img src=\"$ad/images/system/ip.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "iphone"){
        $t = "苹果系统";
        $version = "<img src=\"$ad/images/system/ip.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "netbsd"){
        $t = "NetBSD系统";
        $version = "<img src=\"$ad/images/system/freebsd.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "freebsd"){
        $t = "FreeBSD系统";
        $version = "<img src=\"$ad/images/system/freebsd.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "fedora"){
        $t = "Fedora系统";
        $version = "<img src=\"$ad/images/system/fedora.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "redhat"){
        $t = "RedHat系统";
        $version = "<img src=\"$ad/images/system/redhat.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "debian"){
        $t = "Debian系统";
        $version = "<img src=\"$ad/images/system/debian.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "ubuntu"){
        $t = "Ubuntu系统";
        $version = "<img src=\"$ad/images/system/ubuntu.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "centos"){
        $t = "Centos系统";
        $version = "<img src=\"$ad/images/system/centos.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    if ($t == "suse"){
        $t = "SuSe系统";
        $version = "<img src=\"$ad/images/system/suse.png\" alt=\"$t\" title=\"$t\" width=\"16\" />"; /** 定义图片地址 */
    }
    return $version;
}

/** 这是输出所有信息代码 */
function goout_put(){
echo "<br />Your current IP address is: < ?php echo get_ip(); ?><br />Your IP address location: < ?php echo get_ip_address(); ?><br />Your IP address country and region: < ?php echo get_ip_nation(); ?> < ?php echo outputflag(); ?><br />Your current browser is: < ?php echo get_browser_name(); ?><br />Your current system is: < ?php echo get_os(); ?>";
}

二:在源码目录中的single.php文件中插入以下代码

                          <br /><font color="#7fcce5">sicnature</font> <font>---------------------------------------------------------------------</font>
                          <br />
                            Your current IP address is:  < ?php echo get_ip(); ?>
                          <br />
                           Your IP address location: < ?php echo get_ip_address(); ?>
                          <br />
                           Your IP address country and region: < ?php echo get_ip_nation(); ?> < ?php echo outputflag(); ?>
                          <br />
                           Your current browser is: < ?php echo get_browser_name(); ?>
                          <br />
                           Your current system is: < ?php echo get_os(); ?>
                          <br /><b>Original content, please indicate the source:</b>
                           <br /><a target="_blank" href="http://www.myzhenai.com/">同福客栈论坛</a> | <a target="_blank" href="http://www.myzhenai.com.cn/">海南仙岛</a> | <a target="_blank" href="http://www.haikou-china.com/">海南乡情论坛</a> | <a target="_blank" href="http://jiayu.mybabya.com/">JiaYu Blog</a>
                           <br /><font color="#7fcce5">sicnature</font> <font>---------------------------------------------------------------------</font>
                        <div>
                                Welcome to reprint. Please indicate the source < ?php the_permalink() ?>
                        </div>

PHP获取客户浏览器版本 系统版本 IP地址和IP所在国家源代码及例程

PHP获取客户浏览器版本 系统版本 IP地址和IP所在国家源代码及例程


还有一个方法是使用php官方内置函数 get_browser()进行获取的, 它返回的是一个数组, 只要输出它的browser和platform元素就可以了, 不过它的缺点是它只能获取一些国外注流的浏览器版本,好多国内的浏览器获取不到,并且要下载配置一个庞大的browscap.ini文件.它应该是匹配这个文件里的一些信息的.
利用php内置函数get_browser获取客户端信息

利用php内置函数get_browser获取客户端信息

< ?php
echo $_SERVER['HTTP_USER_AGENT'] . "<br />";//获取访问用户的User Agent信息
$browser = get_browser(null,true); //这是php内置的查询客户端信息函数但是要使用必须参考 http://php.net/manual/zh/function.get-browser.php
echo "您的浏览器是: ".$browser["browser"]. "<br />"; //这是输出客户端浏览器信息
echo "您的系统版本是: ".$browser["platform"]. "<br />";//这是输出客户端系统信息
?>

VMware Workstation Pro 12.0 激活码 许可证 密钥在线获取工具

星期三, 九月 9th, 2015

关键字:VMware Workstation Pro 12.0 激活码 许可证 密钥
这是我写的一个简单的PHP在线读取生成代码,是关于获取VMware Workstation pro 12.0激活码和密钥的小工具.这个只是用于编程交流和探讨,不涉及软件版权,请使用正版VMware Workstation pro 12.0 如果侵犯了您的权益,请联系我们修改或删除工具.
VMware Workstation是收费软件,请尊重著作权,请购买使用正版软件。
VMware Workstation is a billing software, please respect copyright, please buy genuine software use
工具地址:http://jiayu.mybabya.com/vmware.php

VMware Workstation Pro 12.0 激活码 许可证 密钥

VMware Workstation Pro 12.0 激活码 许可证 密钥

WordPress获取垃圾回复IP地址的方法

星期三, 九月 24th, 2014

原创内容,转载清注明出处:http://www.myzhenai.com.cn/post/1875.html http://www.myzhenai.com/thread-16324-1-1.html
这个方法的前提是安装了akismet过滤插件,我的思路是这样的,因为WordPress的垃圾回复比较多,就算安装了akismet拦截也有好多被写入数据库,所以就想着有没有方法把这些垃圾回复的IP提取出来,然后用iptables封禁掉.这样一来就可以减少Mysql数据库的读写和降低服务器的资源占用.一直以来我以为这个功能需要在akismet中更改代码,但是在一朋友的提示下才知道这个是WordPress的内置功能.我们需要用到的函数是 get_comment_author_IP() 这个在官方文本中的注释是返回评论者IP.但是WordPress里还有一个comment_author_IP()函数也能获取评论者IP,但是我们在这里添加却没有办法获得它的返回值,所以要用 get_comment_author_IP(). 我们将下边的代码添加到 /wp-admin/includes/class-wp-comments-list-table.php这个文件中,在comment_author_IP();下边插入代码保存并上传覆盖原文件即可.修改前请先备份这个文件.

    $aip = get_comment_author_IP(); /** 得到ip地址 */
    $txt = file_get_contents("/spam.log"); /** 对比ip地址是否存在文件内,防止重复输入 */
    if (strpos($txt,$aip) === false) /** 如果文件内找不到这个ip地址 */
    {
    $handle = fopen("/spam.log","a+"); /** 打开文件并得到一个句柄,据说a+是写入? */
    fwrite($handle,$aip."/n"); /** 将获得的ip地址添加到文件中 */
    }
    fclose($handle); /** 关闭句柄 */

WordPress 获取 垃圾 回复 IP 地址 方法

WordPress获取垃圾回复IP地址的方法


WordPress spam 获取 垃圾 回复 IP 地址 方法

WordPress获取垃圾回复IP地址的方法


WordPress 函数 get_comment_author_IP 注释

WordPress函数get_comment_author_IP注释


本来我想将代码添加到当前主题中的评论模块comments.php文件中的,但因为我还搞不懂如何判断是否为垃圾回复,为了避免所有回复用户的IP都被收录过滤,所以暂时先不把它加到这个文件中了. 我查找了WordPress官方文档,好像用wp_allow_comment()和wp_get_comment_status()还有wp_blacklist_check()这三个函数可以判断是否为垃圾回复,但是因为我还不懂得如何写这些代码的参数.所以先不弄了,如果您懂得的,欢迎您指点,谢谢了.

易语言的换行符在linux下乱码的解决办法

星期四, 二月 20th, 2014

原创内容,转载请注明出处:http://www.myzhenai.com/thread-16148-1-1.html http://www.myzhenai.com.cn/post/1710.html
在windows下用易语言编写的程序创建了一个iptables脚本,但是我将脚本scp到linux服务器上运行的时候却发生错误了.原来是文档里每行的末尾都被加上了^M,所以才会出现错误.
‘ptables v1.4.7: Invalid target name `DROP
Try `iptables -h’ or ‘iptables –help’ for more information.
我查找了网络上才知道,原来问题出在windows系统和linux系统对换行符的机制是不一样的. 在windows下换行符是/r/n linux下换行符是/n 在易语言里的#换行符常量刚好就是{13,10}也就是/r/n. 知道了这点对我们来说就简单了.只要将这个/r替换掉就可以了. 代码是使用 字符(13) 替换成“”空白字符就可以了.

易语言 换行符 linux 乱码 解决 办法

易语言的换行符在linux下乱码的解决办法


易语言 换行符 linux 乱码 解决 办法

易语言的换行符在linux下乱码的解决办法


易语言 换行符 linux 乱码 解决 办法

易语言的换行符在linux下乱码的解决办法


易语言 换行符 linux 乱码 解决 办法

易语言的换行符在linux下乱码的解决办法

Baidu Sitemap Conversion tool–Google Sitemap转换成百度Sitemap源码

星期四, 四月 4th, 2013

原创内容,转载请注明出处:http://www.myzhenai.com/thread-15478-1-1.html http://www.myzhenai.com.cn/post/981.html
百度网站地图转换工具,这是我为了能更好的吸引百度爬虫而写的一个转换工具,原理只是把SitemapX工具生成的sitemap.xml地图按照百度sitemap原理来转换成百度协议的地图.
百度Sitemap协议
http://www.baidu.com/search/sitemap_help.html
http://www.baidu.com/search/pageop.htm
Baidu Sitemap http://jiayu.mybabya.com/sitemap_baidu.xml
关键字:baidu sitemap sitemap.xml sitemap_baidu.xml 百度网站地图 百度网站地图转换
源码下载:http://www.myzhenai.com.cn/post/981.html
baidu_sitemap
Sitemap

PPS上传插件Api接口开发文档

星期一, 十一月 26th, 2012

这是PPS官方Api接口的开发文档,我只是转载方便以后自己使用,顺便也算是一个分享了. http://open.pps.tv/wiki/plug.php
建议:
使用插件前请先在平台注册一个账户,在设置-申请KEY页面获取用户KEY,稍微修改插件代码(URL中的source值改成用户KEY即可,下面有说明),就可以在此账户下管理自己上传的视频;否则上传的视频都会进入一个PPS账户,上传者本人不能再编辑。
申请KEY页面:http://open.pps.tv/open.php
WordPress插件下载地址:http://api.open.pps.tv/doc/wpupload.zip
Ckeditor编辑器下载地址:http://api.open.pps.tv/doc/ckupload.zip
通用视频上传插件
使用方法:在需要出现上传视频按钮的地方插入下面代码

 <input type="button" id="pps_upload" value="上传视频" class="btn"/>
  <script src="http://api.open.pps.tv/js/jquery.min.js"></script>
  <script src="http://api.open.pps.tv/js/chajian/dialog.js" type="text/javascript"></script>
  <link href="http://api.open.pps.tv/css/dialog.css" rel="stylesheet" type="text/css"/>
  <script>
  var jq = jQuery.noConflict();
  jq(document).ready(function(){
          jq("#pps_upload").click(function(){
            window.top.art.dialog({
            id     : "pps",
            iframe : "http://api.open.pps.tv/index.php?source=out_url&site_type=ge",
            title  : "上传到PPS网络电视",
            width  : "470",
            height : "330",
            lock   : true});
           void(0);
          });
  });
  </script> 

注意:此插件可以用于任何网站,可以把上面代码放到任何想允许上传视频的地方,会出现上传按钮,class样式也可以自行修改。
代码中”http://api.open.pps.tv/index.php?source=out_url”的out_url表示网站的唯一标示key,默认out_url。
如果用户需要管理自己上传的视频,source值为后台设置-申请KEY页面的用户KEY。
URL示例:http://api.open.pps.tv/index.php?source=1234567890987&site_type=ge
上传完成之后,会生成视频的flash播放代码,需要以源码的形式贴在需要展示的地方,即可实现播放
Discuz X上传插件
使用方法:找到发帖模板文件,以下以默认模板为例[修改过模板的请找对应模板文件post_editor_body.htm]
路径:/template/default/forum/post_editor_body.htm,大概在47行找到以下代码

<div class="b2r">
      <p>
          <a id="{$editorid}_autotypeset" title="{lang e_autotypeset}">Autotypeset</a>
          <a id="{$editorid}_justifyleft" title="{lang e_left}">Left</a>
          <a id="{$editorid}_justifycenter" title="{lang e_center}">Center</a>
          <a id="{$editorid}_justifyright" title="{lang e_right}">Right</a>
      </p>
      <p id="{$editorid}_adv_4">
          <a id="{$editorid}_floatleft" title="{lang e_floatleft}">FloatLeft</a>
          <a id="{$editorid}_floatright" title="{lang e_floatright}">FloatRight</a>
          
          
      </p>
  </div>

将以下代码插在上面代码的下面

<input type="button" id="pps_upload" value="上传视频" class="btn"/>
  <script src="http://api.open.pps.tv/js/jquery.min.js"></script>
  <script src="http://api.open.pps.tv/js/chajian/dialog.js" type="text/javascript"></script>
  <link href="http://api.open.pps.tv/css/dialog.css" rel="stylesheet" type="text/css"/>
  <script>
  var jq = jQuery.noConflict();
  jq(document).ready(function(){
          jq("#pps_upload").click(function(){
            window.top.art.dialog({
            id     : "pps",
            iframe : "http://api.open.pps.tv/index.php?source=out_url",
            title  : "上传到PPS网络电视",
            width  : "470",
            height : "330",
            lock   : true});
           void(0);
          });
  });
  </script> 

注意:此插件具有一定的通用性,只要最后的播放地址可以和上传插件格式相同(用[flash][/flash]包播放地址),可以把上面代码放到任何想允许上传视频的地方,会出现上传按钮,class样式可以自行修改。
代码中”http://api.open.pps.tv/index.php?source=out_url”的out_url表示网站的唯一标示key,默认out_url。
如果用户需要管理自己上传的视频,source值为后台设置-申请KEY页面的用户KEY。
URL示例:http://api.open.pps.tv/index.php?source=1234567890987
设置完成之后会在发帖编辑器里面出现一个上传视频按钮,点击选择文件就可实现上传

WordPress上传插件
使用方法:
1.下载上传插件代码并解压 下载:wpupload.zip
2.把代码拷入wordpress插件目录,默认路径为:wp-content/plugins
3.以管理员身份登入wordpress,在插件列表里启用该插件即可在发布文章编辑器中看到绿色上传按钮
注意:tinymce/editor_plugin.js代码中”http://api.open.pps.tv/index.php?source=out_url&site_type=wp”的out_url表示网站的唯一标示key,默认out_url。
如果用户需要管理自己上传的视频,source值为后台设置-申请KEY页面的用户KEY。
URL示例:http://api.open.pps.tv/index.php?source=1234567890987&site_type=wp

Ckeditor编辑器上传插件
下载插件代码到ckeditor/plugins目录,解压缩,如果存在重名的插件,请重新命名。
下载:ckupload.zip
修改ckeditor的配置文件,引入插件[插件为UTF8编码,如需GBK,需要对文件转码,注意汉字不要乱码]。 在config.js文件中有函数CKEDITOR.editorConfig = function( config ),里面添加如下代码:

config.toolbar_Mine =
[
 { name: "document", items: ["Source", "-", "Save", "NewPage", "DocProps", "Preview", "Print", "-",
 "Templates"] },
 { name: "clipboard", items: ["Cut", "Copy", "Paste", "PasteText", "PasteFromWord", "-", "Undo",
 "Redo"] },
 { name: "editing", items: ["Find", "Replace", "-", "SelectAll", "-", "SpellChecker", "Scayt"] },
 { name: "forms", items: ["Form", "Checkbox", "Radio", "TextField", "Textarea", "Select", "Button",
  "ImageButton", "HiddenField"] },
 "/",
 { name: "basicstyles", items: ["Bold", "Italic", "Underline", "Strike", "Subscript", "Superscript",
 "-","RemoveFormat"] },
 { name: "paragraph", items: ["NumberedList", "BulletedList", "-", "Outdent", "Indent", "-",
 "Blockquote",
 "CreateDiv", "-", "JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock", "-", "BidiLtr",
 "BidiRtl"] },
 { name: "links", items: ["Link", "Unlink", "Anchor"] },
 { name: "insert", items: ["Image", "Flash", "Table", "HorizontalRule", "Smiley", "SpecialChar",
  "PageBreak","Iframe"] },
 "/",
 { name: "styles", items: ["Styles", "Format", "Font", "FontSize"] },
 { name: "colors", items: ["TextColor", "BGColor"] },
 { name: "tools", items: ["Maximize", "ShowBlocks", "-", "About"] },
 { name: "extent", items: ["ppsUpload"] }//这里是插件按钮位置,可根据需要自由调整
];
config.toolbar = "Mine";
config.extraPlugins  = (config.extraPlugins ? ",ppsUpload" : "ppsUpload");

使用方法:
1.发帖时点击编辑器中绿色上传按钮,选择文件开始上传视频
2.上传过程中可以修改视频标题与分类
3.上传完成之后会生成视频播放地址,编辑器切换为源码模式,复制粘贴在帖子编辑框内,发布即可
注意:plugin.js代码中”http://api.open.pps.tv/index.php?source=out_url&site_type=ge”的out_url表示网站的唯一标示key,默认out_url。
如果用户需要管理自己上传的视频,source值为后台设置-申请KEY页面的用户KEY。
URL示例:http://api.open.pps.tv/index.php?source=1234567890987&site_type=ge

MCI(媒体控制接口)相关知识

星期二, 四月 26th, 2011

MCI(Media Control Interface)媒体控制接口是MircroSoft提供的一组多媒体设备和文件的标准接口,它的好处是可以方便地控制绝大多数多媒体设备包括音频、视频、影碟、录像等多媒体设备,而不需要知道它们的内部工作状况。但是古人云:成也萧何,败也萧何。MCI虽然看上去高大全,但对于一些高级应用来说,它是远远不够的。

MCI的控制方式:

一般说来,程序员使用两个函数就可以与MCI打交道了:

MCIERROR mciSendCommand(MCIDEVICEID wDeviceID, UINT uMsg, DWORD dwFlags, DWORD dwParam);
命令字符串方式,用接近于日常生活用语的方式发送控制命令,适用于高级编程如VB、TOOLBOOK等。

MCIERROR mciSendString(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback);
命令消息方式,用专业语法发送控制消息,适用于VC等语言编程,此方式直接与MCI设备打交道。

对于mciSendCommand,第一个参数指定了设备标识,这个标识会在程序员打开MCI设备时由系统提供。第二个参数指定将如何控制设备,详细请查阅后面“MCI指令”一栏。第三个参数为访问标识,第四个参数一般是一个数据结构,标识程序在访问MCI时要的一些信息。有关详细资料,请查阅本光盘配套书。

对于mciSendString,第一个参数为一串控制字符串,返回信息由系统填入第二个参数,第三个参数指明返回信息的最大长度,若对MCI装置设定了”notify”标志则需要在第四个参数填上返回窗口句柄。

举例:
mciSendCommand(DeviceID, MCI_CLOSE, NULL, NULL); // 关闭一个MCI设备
mciSendString(“open aaa.avi”, 0, 0, 0); // 打开文件”aaa.avi”

MCI的设备类型:

设备描述 描述字符串 说明
MCI_ALL_DEVICE_ID 所有设备
MCI_DEVTYPE_ANIMATION Animation 动画设备
MCI_DEVTYPE_CD_AUDIO Cdaudio CD音频
MCI_DEVTYPE_DAT Dat 数字音频
MCI_DEVTYPE_DIGITAL_VIDEO Digitalvideo 数字视频
MCI_DEVTYPE_OTHER Other 未定义设备
MCI_DEVTYPE_OVERLAY Overlay 重叠视频
MCI_DEVTYPE_SCANNER Scanner 扫描仪
MCI_DEVTYPE_SEQUENCER Sequencer MIDI 序列器
MCI_DEVTYPE_VCR Vcr 合式录像机
MCI_DEVTYPE_VIDEODISC Videodisc 激光视盘
MCI_DEVTYPE_WAVEFORM_AUDIO waveaudio Wave 音频

对于未在上面定义的MCI设备,用户可查看system.ini文件中[mci]部分,例如:

[mci]
cdaudio=mcicda.drv
sequencer=mciseq.drv
waveaudio=mciwave.drv
avivideo=mciavi.drv
videodisc=mcipionr.drv
vcr=mcivisca.drv
ActiveMovie=mciqtz.drv
QTWVideo=mciqtw.drv
MPEGVideo=C:\PROGRA~1\XING\XINGMP~1\xmdrv95.dll

其中最后两句分别指明了Apple的QuickTime设备,设备名为”QTWVidio”、MPEG影像设备,设备名为”MPEGVideo”。
//——————————

在MCI编程中,既可以将设备描述当设备名,也可以将描述字符串当设备名,一个极端偷懒的办法是程序员不要在程序中指定设备名,Windows将自动根据文件扩展名识别设备类型。
举个例子来说,打开一个多媒体文件有以下三种方式:

[1]:自动识别:打开一个”WAV”文件
MCI_OPEN_PARMS mciOpen;
mciOpen.lpstrDeviceType = 0;
mciOpen.lpstrElementName = “aaa.wav”;
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciOpen);
// 本文转自 C++Builder研究 – http://www.ccrun.com/article.asp?i=629&d=3c23i7
[2]:指定设备描述:打开CD播放器
MCI_OPEN_PARMS mciOpen;
mciOpen.lpstrDeviceType = (LPSTR)MCI_DEVTYPE_CD_AUDIO ;
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID, (DWORD)&mciOpen);

[3]:指定描述字符串: 打开一个AVI文件
MCI_OPEN_PARMS mciOpen;
mciOpen.lpstrDeviceType = “avivideo”;
mciOpen.lpstrElementName = “aaa.avi”;
mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&mciOpen);

注意三种打开方式中,函数第三个参数的区别,后面会讲到这种区别。

MCI指令

MCI_BREAK 设置中断键,缺省是”CTRL+BREAK”
MCI_CAPTURE 抓取当前帧并存入指定文件,仅用于数字视频
MCI_CLOSE 关闭设备
MCI_CONFIGURE 弹出配置对话框,仅用于数字视频
MCI_COPY 拷贝数据至剪贴板
MCI_CUE 延时播放或录音
MCI_CUT 删除数据
MCI_DELETE 删除数据
MCI_ESCAPE 仅用于激光视频
MCI_FREEZE 将显示定格
MCI_GETDEVCAPS 获取设备信息
MCI_INDEX 当前屏幕显示与否,仅用于VCR设备
MCI_INFO 获取字符串信息
MCI_LIST 获取输入设备数量,支持数字视频和VCR设备
MCI_LOAD 装入一个文件
MCI_MARK 取消或做一个记号,与MCI_SEEK配套
MCI_MARK 取消或做一个记号,与MCI_SEEK配套
MCI_MONITOR 为数字视频指定报告设备
MCI_OPEN 打开设备
MCI_PASTE 粘帖数据
MCI_PAUSE 暂停当前动作
MCI_PLAY 播放
MCI_PUT 设置源、目的和边框矩形
MCI_QUALITY 定义设备缺省质量
MCI_RECORD 开始录制
MCI_RESERVE 分配硬盘空间
MCI_RESTORE 拷贝一个bmp文件至帧缓冲
MCI_RESUME 使一个暂停设备重新启动
MCI_SAVE 保存数据
MCI_SEEK 更改媒体位置
MCI_SET 设置设备信息
MCI_SETAUDIO 设置音量
MCI_SETTIMECODE 启用或取消VCR设备的时间码
MCI_SETTUNER 设置VCR设备频道
MCI_SETVIDEO 设置video参数
MCI_SIGNAL 在工作区上设置指定空间
MCI_STATUS 获取设备信息
MCI_STEP 使播放设备跳帧
MCI_STOP 停止播放
MCI_SYSINFO 返回MCI设备信息
MCI_UNDO 取消操作
MCI_UNFREEZE 使使用MCI_UNFREEZE的视频缓冲区恢复运动
MCI_UPDATE 更新显示区域
MCI_WHERE 获取设备裁减矩形
MCI_WINDOW 指定图形设备窗口和窗口特性

其中比较常用的指令有MCI_OPEN、MCI_CLOSE、MCI_PLAY、MCI_STOP、MCI_PAUSE、MCI_STATUS等等。

【多媒体编程应用】MCI编程之 mciSendCommand

星期二, 四月 26th, 2011

武汉石化设计院电算室 周红汉

使用MCI API,源文件中需要包含头文件 Mmsystem.h,在Project->Settings->Link->Object/libray module中加入库 Winmm.lib。

1、MCI简介

  MCI(Media Control Interface,媒体控制接口)向Windows程序提供了在高层次上控制媒体设备接口的能力。程序不必关心具体设备,就可以对激光唱机(CD)、视盘机、波形音频设备、视频播放设备和MIDI设备等媒体设备进行控制。
  对于程序员来说,可以把MCI理解为设备面板上的一排按键,通过选择不同的按键(发送不同的MCI命令)可以让设备完成各种功能,而不必关心设备内部实现。
  比如,对于play,视盘机和CD机有不同的反应(一个是播放视频,一个播放音频),而对用户来说却只需要按同一按钮。

  应用程序通过向MCI发送命令来控制媒体设备。MCI命令接口分命令字符串和命令消息两种,两者具有相同的功能。命令字符串具有使用简单的特点,但是它的执行效率不如命令消息。

  所有的MCI命令字符串都是通过多媒体API函数mciSendString传递给MCI的,该函数的声明为:
    MCIERROR mciSendString(
      LPCTSTR lpszCommand,    //MCI命令字符串
      LPTSTR lpszReturnString, //存放反馈信息的缓冲区
      UINT  cchReturn,     //缓冲区的长度
      HANDLE hwndCallback    //回调窗口的句柄,一般为NULL
    ); //若成功则返回0,否则返回错误码。
  该函数返回的错误码可以用mciGetErrorString函数进行分析,该函数的声明为:
    BOOL mciGetErrorString(
      DWORD fdwError,   //函数mciSendString返回的错误码
      LPTSTR lpszErrorText, //接收描述错误的字符串的缓冲区
      UINT  cchErrorText  //缓冲区的长度
    );

  下面是使用mciSendString函数的一个简单例子:
    char buf[50];
    MCIERROR mciError;
    mciError=mciSendString(“open cdaudio”,buf,strlen(buf),NULL);
    if(mciError)
    {
      mciGetErrorString(mciError,buf,strlen(buf));
      AfxMessageBox(buf);
      return;
    }
  open cdaudio命令打开CD播放器,如果出错(如驱动器内没有CD)则返回错误码,此时可以用mciGetErrorString函数取得错误信息字符串。

2、MCI设备

  open是MCI打开设备的命令,cdaudio是MCI设备名。MCI的设备类型如下:
    animation  动画设备
    cdaudio   CD播放器
    dat     数字音频磁带机
    digitalvideo 某一窗口中的数字视频(不基于GDI)
    other    未定义的MCI设备
    overlay   重叠设备(窗口中的模拟视频)
    scanner   图象扫描仪
    sequencer  MIDI序列器
    videodisc  视盘机
    waveaudio  播放数字波形文件的音频设备

  设备名是在注册表或SYSTEM.INI的[mci]部分定义的,典型的[mci]段如下:
    [mci]
    cdaudio=mcicda.drv
    sequencer=mciseq.drv
    waveaudio=mciwave.drv
    avivideo=mciavi.drv
    videodisc=mcipionr.drv
  等号的左边是设备名,右边是对应的MCI驱动程序。当安装了新的MCI驱动程序时,系统要用不同的设备名来区分。

3、MCI命令

  使用MCI设备一般包括打开、使用和关闭三个过程,常用的MCI命令有:
    open    打开设备
    close    关闭设备
    play    开始设备播放
    stop    停止设备的播放或记录
    record   开始记录
    save    保存设备内容
    pause    暂停设备的播放或记录
    resume   恢复暂停播放或记录的设备
    seek    改变媒体的当前位置
    capacility 查询设备能力
    info    查询设备的信息
    status   查询设备状态信息
  MCI的大部分命令可以控制不同的媒体设备,但其中record和save命令并不是所有MCI设备都可以使用。
  MCI命令的使用是很随意的,只要先打开,最后关闭,中间可以随意调用各种命令。

(1) open 打开设备

  MCI设备使用前必须先打开,当然,使用后也必须要关闭,以免影响他人的使用。

  open device_name type device_type alias device_alias
    device_name     要使用的设备名,通常是文件名。
    type device_type  设备类型,例如waveaudio或sequencer,可省略。
    alias device_alias 设备别名,指定后可在其他命令中代替设备名。

(2) play 开始设备播放

  MCI设备打开后即可以播放,可使用设备名或别名。

  play device_alias from pos1 to pos2 wait repeat
    若省略from则从当前磁道开始播放,若省略to则播放到结束。
    若指明wait则等到播放完毕命令才返回。
    若指明repeat则会不停的重复播放。
    若同时指明wait和repeat则命令不会返回,本线程产生堵塞,通常会引起程序失去响应。

(3) 播放CD

  void CTttView::OnOpenCD()
  {
    mciSendString(“open cdaudio”,NULL,0,NULL);
    mciSendString(“play cdaudio”,NULL,0,NULL);
  );

  void CTttView::OnStopCD()
  {
    mciSendString(“stop cdaudio”,NULL,0,NULL);
    mciSendString(“close cdaudio”,NULL,0,NULL);
  );

  还可以:
    pause cdaudio  暂停播放。
    resume cdaudio 继续被暂停的播放。
    seek cdaudio to < 位置> 移动到指定磁道。
    set cdaudio door open/closed 弹出或缩进CD盘。

(4) 播放多媒体文件

  void CTttView::OnMyMenu()
  {
    mciSendString(“open myfolder\\tada.wav alias aa”,NULL,0,NULL);
  或 mciSendString(“open myfolder\\flourish.mid alias aa”,NULL,0,NULL);
  或 mciSendString(“open myfolder\\clock.avi alias aa”,NULL,0,NULL);
    mciSendString(“play aa wait”,NULL,0,NULL);
    mciSendString(“close aa”,NULL,0,m_hWnd);
  );

(5) 录制声音

  void CTttView::OnStartRecord()
  {
    mciSendString(“open new type waveaudio alias aa”,NULL,0,NULL);
    mciSendString(“record aa”,NULL,0,NULL);
  );

  void CTttView::OnStopRecord()
  {
    mciSendString(“save aa c:\\aaa.wav wait”,NULL,0,NULL);
    mciSendString(“close aa”,NULL,0,NULL);
  );

4、MCI命令消息

  到目前为止,我们使用的都是MCI命令字符串。可以发现,命令字符串具有简单易学的优点,但这种接口与C/C++的风格相去甚远,如果程序要查询和设置大量数据,那么用字符串的形式将很不方便。
  MCI的命令消息接口提供了C语言接口,它速度更快,并且更能符合C/C++程序员的需要。

  所有MCI命令消息都是通过mciSendCommand函数发送的,函数声明为:
    MCIERROR mciSendCommand(
      MCIDEVICEID wIDDevice,  //设备的ID,在打开设备时不用该参数
      UINT    uMsg,    //命令消息
      DWORD    fdwCommand, //命令消息的标志
      DWORD    dwParam   //指向包含命令消息参数的结构
    ); //若成功则返回0,否则返回错误码

  命令消息uMsg与命令字符串是对应的,例如,open与MCI_OPEN完成的是一样的功能。
  变量wDeviceID用来保存设备的ID,系统用ID来标识不同的设备,以保证命令发给正确的对象。

  void CTttView::OnMyMenu()
  {
    MCI_OPEN_PARMS mciOpen;
    UINT wDeviceID;
    mciOpen.lpstrDeviceType = “avivideo”;
    mciOpen.lpstrElementName = “myfolder\\clock.avi”;
    mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&mciOpen);
    wDeviceID=mciOpen.wDeviceID;
    MCI_PLAY_PARMS mciPlay;
    mciSendCommand(wDeviceID, MCI_PLAY, MCI_WAIT, (DWORD)&mciPlay);
  );

  可以看出,用命令消息比用命令字符串要复杂的多,但它的执行效率高。
===============================================

—- 加入音乐是增强应用程序功能的所有方法中最简单的一个。几乎每个计算机游戏或多 媒体程序都以某种MIDI或CD音乐为背景。音乐可以使用户心情愉快;在合适的场合播 放恰当的音乐能够使程序员和他的VC++程序焕发光彩。

第一部分 MIDI的播放
—- 乐器数字化接口(MIDI)是由音乐界的一些大公司(包括生产电子音乐合成器的公司) 制订的一项协议,后来被计算机产业所采用并成为多媒体音乐文件的标准格式。MIDI文件 一般较小,对硬件设备的要求高。

—- 一、 原理

—- 虽然MicroSoft支持MIDI文件,然而Visual C++或MFC并没有创建任何组件来实现 这种支持,但是MicroSoft API提供了三种不同的方法来实现MIDI的播放:

MCI(The Media Control Interface)。这是最基本的方法,本文将详细讨论这种方法。

流缓冲器。这种格式允许应用程序为MIDI数据分配缓冲器。在需要精确控制MIDI播放的时候,流缓冲器将很有用处。

低级MIDI设备。需要完全控制MIDI数据的应用程序可以使用这种方法。
—- MCI可以通过mciSendCommand()和mciSendString()来完成,本文仅使用mciSendCommand()函数。

—- 原型:DWORD mciSendCommand(UINT wDeviceID,UINT wMessage,DWORD dwParam1,DWORD dwParam2);

参数: wDeviceID:接受消息的设备ID
wMessage:MCI命令消息
dwParam1:命令的标志位
dwParam2:所使用参数块的指针

—- 返值:调用成功,返回零;否则,返回双字中的低字存放有错误信息。

二MIDI的播放控制
—- 1. 打开设备

MCI_OPEN_PARMS OpenParms;
OpenParms.lpstrDeviceType =
(LPCSTR) MCI_DEVTYPE_SEQUENCER;//MIDI类型
OpenParms.lpstrElementName = (LPCSTR) Filename;
OpenParms.wDeviceID = 0;
mciSendCommand (NULL, MCI_OPEN,
MCI_WAIT | MCI_OPEN_TYPE |
MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT,
(DWORD)(LPVOID) &OpenParms)

—- MCI设备ID指明打开了哪个设备,当发送了MCI_OPEN命令时,这个值在参数块中返回——应被保存备用。

—- 2. 关闭设备

mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL);

—- 3. 播放

MCI_PLAY_PARMS PlayParms;
PlayParms.dwFrom = 0;
// 指定从什么地方(时间)播放
mciSendCommand (m_wDeviceID, MCI_PLAY,
MCI_FROM, (DWORD)(LPVOID)
&PlayParms));

—- 4. 暂停

MCI_PLAY_PARMS PlayParms;
mciSendCommand (m_wDeviceID, MCI_PAUSE, 0,
(DWORD)(LPVOID) &PlayParms);

—- 5. 停止

mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL);

—- 6. 跳跃

* 跳转到任意地方
MCI_SEEK_PARMS SeekParms;
SeekParms.dwTo = (nMinute * 60 + nSecond) * 1000;
//跳转的目标时间,时间单位为毫秒
mciSendCommand (m_wDeviceID, MCI_SEEK, MCI_TO
| MCI_WAIT,(DWORD)(LPVOID)
&SeekParms);
* 跳到文件头
mciSendCommand (m_wDeviceID, MCI_SEEK,
MCI_SEEK_TO_START, NULL);
* 跳到文件尾
mciSendCommand (m_wDeviceID, MCI_SEEK,
MCI_SEEK_TO_END, NULL);

—- 7. 查询当前信息

MCI_STATUS_PARMS StatusParms;
StatusParms.dwItem = MCI_SEQ_STATUS_DIVTYPE;
mciSendCommand (m_wDeviceID, MCI_STATUS,
MCI_WAIT | MCI_STATUS_ITEM,
(DWORD)(LPVOID) &StatusParms);
返回信息存放于StatusParms.dwReturn中。
MCI_STATUS标志
MCI_STATUS_LENGTH 获得文件长度
MCI_STATUS_MODE 获得文件播放的当前状态
MCI_STATUS_POSITION 获得文件播放的当前位置
MCI_STATUS_TIME_FORMAT 获得当前的时间格式
MCI_SEQ_STATUS_DIVTYPE 判断文件是PPQN类型还是SMPTE类型
MCI_SEQ_STATUS_TEMPO 获得当前播放速度,PQRN类型,
此值为节拍/分,SMPTE类型,此值为祯/秒

—- 8. 设置时间格式及播放速度

MCI_SET_PARMS SetParms;
SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
//设置时间单位为毫秒
mciSendCommand (m_wDeviceID,
MCI_SET, MCI_SET_TIME_FORMAT,
(DWORD)(LPVOID) &SetParms);
MCI_SEQ_SET_TEMPO 设置播放速度,
PQRN类型,此值为节拍/分,
SMPTE类型,此值为祯/秒

第二部分 WAV文件的播放
—- 一、原理

—- MicroSoft API提供了三种不同的方法来实现WAV的播放:

PlaySound()函数。它可以通过单行编码来播放Wave格式的声音。此函数有两个限制:必须将声音数据完整地载入物理内存;数据格式必须被所配置的某一音频驱动器支 持。根据经验,PlaySound()适用于100K以下的文件。

MCI(The Media Control Interface),与上一章播放MIDI文件相似,可以播放100K 以上的文件。

低级Wave音频设备。用这些设备可以运行完全控制Wave数据的应用文件。
—- 二、 WAV文件播放控制

—- 因为同样使用MCI,与上一章相同,只列出不同的部分。

—- 1. 打开设备

—- 将MIDI的MCI_DEVTYPE_SEQUENCER 改为”waveaudio”

—- 2. 录音

MCI_RECORD_PARMS RecordParms;
mciSendCommand (m_wDeviceID, MCI_RECORD,
NULL, (DWORD)(LPVOID)
&RecordParms);

—- 3. 保存录音

MCI_SAVE_PARMS SaveParms;
SaveParms.lpfilename = (LPCSTR) Filename;
mciSendCommand (m_wDeviceID, MCI_SAVE,
MCI_SAVE_FILE | MCI_WAIT,
(DWORD)(LPVOID) &SaveParms);

第三部分 CD的播放
—- CD的独特优势在于,它由作曲家设计,并由音乐厂家生产。不同的计算机播放MIDI 文件时,声音效果也不一样,但是CD的声音效果总是相同的。高品质的音频对计算机用 户产生的效果会使你感到吃惊。 我们依然采用MCI播放CD,大部分的播放控制与前两部分相同,只列出不同的部分

—- 1. 开光驱门

mciSendCommand (m_wDeviceID, MCI_SET,
MCI_SET_DOOR_OPEN, NULL);

—- 2. 关光驱门

mciSendCommand (m_wDeviceID, MCI_SET,
MCI_SET_DOOR_CLOSED, NULL);

—- 3. 打开设备

将MIDI的MCI_DEVTYPE_SEQUENCER 改为MCI_DEVTYPE_CD_AUDIO

—- 4. 播放

—- 指定播放起点必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化

—- 5. 查询当前信息

MCI_STATUS_CURRENT_TRACK 得到当前曲目
MCI_STATUS_LENGTH 得到CD或指定曲目长度
MCI_STATUS_MODE 得到驱动器的当前状态
MCI_STATUS_NUMBER_OF_TRACKS 得到CD曲目的数目
MCI_STATUS_POSITION 得到当前格式下的位置
MCI_STATUS_READY 检查设备是否就绪
MCI_STATUS_TIME_FORMAT 得到当前时间格式
MCI_STATUS_MEDIA_divSENT 检查以确认CD是否在驱动器内
MCI_CDA_STATUS_TYPE_TRACK 检查已确认某曲目是否为音频曲目

—- 注意:

使用MCI_STATUS_LENGTH参数查询CD 及曲目长度,返回值通过调用MCI_MSF_MINUTE(),MCI_MSF_SECOND()转换为分、秒。

MCI_STATUS_POSITION参数返回值调用MCI_TMSF_TRACK(), MCI_TMSF_MINUTE(), MCI_TMSF_SECOND(),MCI_TMSF_FRAME才能得到当前的位置的道、分、秒、帧。
—- 6. 跳跃

—- 跳转的目标必须经过MCI_MAKE_TMSF(Track,Minute,Second,Frame)转化最好将上述三种格式分开建类,或做成动态连接库。在 Project– >Setting– >Link– >Object/library modules中加入winmm.lib,源程序中包含。

—- MCI调用简单,功能强大,可以满足日常多媒体编程的基本需要。但是,MCI一次只能播放一个文件,使用DirectSound技术可以实现八个以上WAV文件的同时播放。