/// <summary> /// RTP数据包类 /// </summary> public class RTPPacket { /// <summary> /// 获取数据包头信息V /// </summary> public int V { get; private set; } /// <summary> /// 获取数据包头信息P /// </summary> public bool P { get; private set; } /// <summary> /// 获取数据包头信息X /// </summary> public bool X { get; private set; } /// <summary> /// 获取数据包头信息CC /// </summary> public int CC { get; private set; } /// <summary> /// 获取数据包头信息M /// </summary> public bool M { get; private set; } /// <summary> /// 获取数据包头信息PT /// </summary> public int PT { get; private set; } /// <summary> /// 获取数据包头信息SequenceNumber /// </summary> public ushort SequenceNumber { get; private set; } /// <summary> /// 获取数据包头信息Timestamp /// </summary> public uint Timestamp { get; private set; } /// <summary> /// 获取数据包头信息SSRC /// </summary> public uint SSRC { get; private set; } /// <summary> /// 获取数据包头信息CSRC /// </summary> public List<uint> CSRC { get; private set; } /// <summary> /// 获取数据包有效数据 /// </summary> public byte[] Payload { get; private set; } /// <summary> /// 获取数据包有效数据长度 /// </summary> public uint PayloadSize { get; private set; } /// <summary> /// 获取数据包头信息长度 /// </summary> public uint HeaderSize { get; private set; } /// <summary> /// 构造RTP数据包类 /// </summary> /// <param name="buffer">RTP数据包数据</param> public RTPPacket(byte[] buffer) { // 判断数据长度是否有效 if (buffer.LongLength > 12) { // 根据RTP数据包头信息解析数据 byte item = buffer[0]; V = item >> 6; P = Convert.ToBoolean((item >> 5) & 1); X = Convert.ToBoolean((item >> 4) & 1); CC = item & 15; item = buffer[1]; M = Convert.ToBoolean((item >> 7) & 1); PT = item & 127; SequenceNumber = ReadUInt16(buffer[2], buffer[3]); Timestamp = ReadUInt32(buffer[4], buffer[5], buffer[6], buffer[7]); SSRC = ReadUInt32(buffer[8], buffer[9], buffer[10], buffer[11]); int index = 12; CSRC = new List<uint>(); for (var i = 0; i < CC; i++) { index = i * 4 + index; uint csrc = ReadUInt32(buffer[index], buffer[index + 1], buffer[index + 2], buffer[index + 3]); CSRC.Add(csrc); } index = CC * 4 + index; if (X) { index++; index += buffer[index]; } Payload = buffer.Skip(index).ToArray(); PayloadSize = (uint)Payload.LongLength; HeaderSize = (uint)(CSRC.Count * 4 + 12); } } /// <summary> /// 构造RTP数据包类 /// </summary> /// <param name="packet">RTP数据包</param> public RTPPacket(RTPPacket packet) { // 复制RTP数据包成员 V = packet.V; P = packet.P; X = packet.X; CC = packet.CC; M = packet.M; PT = packet.PT; SequenceNumber = packet.SequenceNumber; Timestamp = packet.Timestamp; SSRC = packet.SSRC; CSRC = packet.CSRC; Payload = packet.Payload; PayloadSize = packet.PayloadSize; HeaderSize = packet.HeaderSize; Debug.WriteLine(ToString()); } /// <summary> /// 根据四个字节读取UInt32数据 /// </summary> /// <param name="byte1">字节1</param> /// <param name="byte2">字节2</param> /// <param name="byte3">字节3</param> /// <param name="byte4">字节4</param> /// <returns>返回UInt32数据</returns> private uint ReadUInt32(byte byte1, byte byte2, byte byte3, byte byte4) { uint uint1 = (uint)(byte1 << 24); uint uint2 = (uint)(byte2 << 16); uint uint3 = (uint)(byte3 << 8); uint uint4 = (uint)byte4; return (uint)(((uint1 | uint2) | uint3) | uint4); } /// <summary> /// 根据两个字节读取UInt16数据 /// </summary> /// <param name="byte1">字节1</param> /// <param name="byte2">字节2</param> /// <returns>返回UInt16数据</returns> private ushort ReadUInt16(byte byte1, byte byte2) { ushort ushort1 = (ushort)(byte1 << 8); ushort ushort2 = (ushort)byte2; return (ushort)(ushort1 | ushort2); } /// <summary> /// 重载获取字符串方法 /// </summary> /// <returns>返回RTP数据包对象的字符串表现形式</returns> public override string ToString() { StringBuilder builder = new StringBuilder(); builder.Append(string.Format("V: {0}, ", V)); builder.Append(string.Format("P: {0}, ", P)); builder.Append(string.Format("X: {0}, ", X)); builder.Append(string.Format("CC: {0}, ", CC)); builder.Append(string.Format("M: {0}, ", M)); builder.Append(string.Format("PT: {0}, ", PT)); builder.Append(string.Format("SequenceNumber: {0}, ", SequenceNumber)); builder.Append(string.Format("Timestamp: {0}, ", Timestamp)); builder.Append(string.Format("SSRC: {0}, ", SSRC)); builder.Append(string.Format("CSRC: {0}, ", string.Join(" ", CSRC))); builder.Append(string.Format("PayloadSize: {0};", PayloadSize)); return builder.ToString(); } /// <summary> /// 重载对象是否相同 /// </summary> /// <param name="obj">要比较的对象</param> /// <returns>返回对象是否相同</returns> public override bool Equals(object obj) { RTPPacket packet = obj as RTPPacket; if (packet == null) { return false; } else { return SequenceNumber == packet.SequenceNumber; } } /// <summary> /// 重载获取HashCode /// </summary> /// <returns>返回SequenceNumber</returns> public override int GetHashCode() { return SequenceNumber; } /// <summary> /// ==运算符重载 /// </summary> /// <param name="packet1">左边RTP数据包对象</param> /// <param name="packet2">右边RTP数据包对象</param> /// <returns>返回是否相等</returns> public static bool operator ==(RTPPacket packet1, RTPPacket packet2) { if (ReferenceEquals(packet1, packet2)) { return true; } else if (ReferenceEquals(packet1, null) || ReferenceEquals(packet2, null)) { return false; } else { return packet1.Equals(packet2); } } /// <summary> /// !=运算符重载 /// </summary> /// <param name="packet1">左边RTP数据包对象</param> /// <param name="packet2">右边RTP数据包对象</param> /// <returns>返回是否不相等</returns> public static bool operator !=(RTPPacket packet1, RTPPacket packet2) { return !(packet1 == packet2); } }
分类: 程序开发
程序员的自我修养
关于Android中判断Service是否正在运行的说明
/** * 判断服务是否正在运行 * * @param context 上下文 * @param serviceName 服务名称,包名加类名 * @return 服务正在运行则返回true,否则返回false */ public static boolean isServiceWorked(Context context, String serviceName) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); ArrayList<ActivityManager.RunningServiceInfo> runningServices = (ArrayList<ActivityManager.RunningServiceInfo>) activityManager.getRunningServices(Integer.MAX_VALUE); for (ActivityManager.RunningServiceInfo runningService : runningServices) { String name = runningService.service.getClassName().toString(); if (name.equals(serviceName)) { return true; } } return false; }
关于JavaScript中重置URL参数的说明
/** * 构造URL参数信息 * nameValues:要构造的URL参数信息,由键值对构成,如name=value * includeEmpty:是否包括空值参数 * return:返回构造后URL参数信息 */ function buildUrlParams(nameValues, includeEmpty) { // 定义新的URL参数字典 var newParams = {}; // 构造要设置的URL参数信息 var nameValue = nameValues instanceof Array ? nameValues.join("&") : nameValues; // 拆分URL参数信息 var oldParams = nameValue.split("&"); // 遍历每个URL参数 for (var i = 0, length = oldParams.length; i < length; i++) { // 获取URL参数的键值对 var items = oldParams[i].split("="); // 判断URL参数的键值对是否有效 if (items.length) { // 获取参数名 var name = items[0]; // 判断参数名是否有效 if (name) { // 获取参数值 var value = null; if (items.length > 1) { value = items[1] } // 判断URL参数的键值对是否有效 if (includeEmpty || value) { // 获取已构造的参数值 var values = newParams[name]; if (!values) { // 没有构造过参数则添加新的参数信息 values = newParams[name] = []; } // 添加新的参数值 if (value) { // 如参数未URL编码则对其进行编码 //value = decodeURIComponent(value) == value ? encodeURIComponent(value) : value; values.push(value); } } } } } // 返回构造后URL参数信息 return newParams; } /** * 设置URL参数 * url:要设置参数的URL * nameValues:要设置的参数信息,由键值对构成,如name=value * return:返回设置参数后的URL */ function setUrlParams(url, nameValues) { // 构造要设置的URL参数信息 var newParams = buildUrlParams(nameValues, true); // 获取URL地址中参数开始索引 var index = url.indexOf("?"); // 判断URL地址中是否有参数 if (index >= 0) { // 构造原始的URL参数信息 var oldParams = buildUrlParams(url.substring(index + "?".length)); // 获取不带参数的URL地址 url = url.substring(0, index); // 遍历要设置的URL参数信息 for (var name in newParams) { // 将要设置的URL参数信息覆盖添加到原始参数信息中 oldParams[name] = newParams[name]; } // 重新设置URL参数信息 newParams = oldParams; } // 构造URL参数键值对 var params = []; for (var name in newParams) { var values = newParams[name]; if (values.length) { params.push(name + "=" + values.join(",")); } } // 判断是否有参数 if (params.length) { // 返回构造后的URL地址 return url + "?" + params.join("&"); } else { // 没有参数则返回不带参数的URL地址 return url; } }
关于C#中重置URL参数的说明
/// <summary> /// 构造URL参数信息 /// </summary> /// <param name="includeEmpty">是否包括空值参数</param> /// <param name="nameValues">要构造的URL参数信息,由键值对构成,如name=value</param> /// <returns>返回构造后URL参数信息</returns> public virtual Dictionary<string, List<object>> BuildUrlParams(bool includeEmpty, params object[] nameValues) { // 定义新的URL参数字典 Dictionary<string, List<object>> newParams = new Dictionary<string, List<object>>(); // 构造要设置的URL参数信息 string nameValue = string.Join("&", nameValues); // 拆分URL参数信息 string[] oldParams = nameValue.Split(new string[] { "&" }, StringSplitOptions.RemoveEmptyEntries); // 遍历每个URL参数 for (int i = 0, length = oldParams.Length; i < length; i++) { // 获取URL参数的键值对 string[] items = oldParams[i].Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); // 判断URL参数的键值对是否有效 if (items.Length > 0) { // 获取参数名 string name = items[0]; // 获取参数值 string value = null; if (items.Length > 1) { value = items[1]; } // 判断URL参数的键值对是否有效 if (includeEmpty || value != null) { // 获取已构造的参数值 List<object> values; if (!newParams.TryGetValue(name, out values)) { // 没有构造过参数则添加新的参数信息 values = newParams[name] = new List<object>(); } // 添加新的参数值 if (value != null) { // 如参数未URL编码则对其进行编码 value = HttpUtility.UrlDecode(value, Encoding) == value ? HttpUtility.UrlEncode(value, Encoding) : value; values.Add(value); } } } } // 返回构造后URL参数信息 return newParams; } /// <summary> /// 设置URL参数 /// </summary> /// <param name="url">要设置参数的URL</param> /// <param name="nameValues">要设置的参数信息,由键值对构成,如name=value</param> /// <returns>返回设置参数后的URL</returns> public virtual string SetUrlParams(string url, params object[] nameValues) { // 构造要设置的URL参数信息 Dictionary<string, List<object>> newParams = BuildUrlParams(true, nameValues); // 获取URL地址中参数开始索引 int index = url.IndexOf("?"); // 判断URL地址中是否有参数 if (index >= 0) { // 构造原始的URL参数信息 Dictionary<string, List<object>> oldParams = BuildUrlParams(false, url.Substring(index + "?".Length)); // 获取不带参数的URL地址 url = url.Substring(0, index); // 判断是否存在原始URL参数信息 if (oldParams.Count > 0) { // 遍历要设置的URL参数信息 foreach (KeyValuePair<string, List<object>> item in newParams) { // 将要设置的URL参数信息覆盖添加到原始参数信息中 oldParams[item.Key] = item.Value; } // 重新设置URL参数信息 newParams = oldParams; } } // 判断是否有参数 if (newParams.Count > 0) { // 构造新的URL参数信息 string newParam = string.Join("&", newParams.Where(n => n.Value.Count > 0).Select(n => string.Format("{0}={1}", n.Key, string.Join(",", n.Value)))); // 返回构造后的URL地址 return string.Format("{0}?{1}", url, newParam); } else { // 没有参数则返回不带参数的URL地址 return url; } }
关于JavaScript中设置URL参数的说明
/** * 设置URL参数 * url:要设置参数的URL * name:参数名 * value:参数值 * return:返回设置参数后的URL */ function setUrlParam(url, name, value) { // 获取URL地址中参数开始索引 var index = url.indexOf("?"); // 判断URL地址中是否有参数 if (index >= 0) { // 获取不带参数的URL地址 var baseUrl = url.substring(0, index); // 获取URL地址中的参数信息 var paramUrl = url.substring(index); // 获取要设置的参数的索引 index = paramUrl.indexOf("?" + name + "="); // 判断要设置的参数是否是第一个参数 if (index == 0) { // 获取要设置的参数后面的参数开始的索引 index = paramUrl.indexOf("&"); // 判断后面是否有参数 if (index >= 0) { // 有参数则构造新的URL地址 return baseUrl + "?" + name + "=" + value + paramUrl.substring(index) } else { // 没参数则构造新的URL地址 return baseUrl + "?" + name + "=" + value; } } else { // 不是第一个参数则获取要设置参数的索引位置 index = paramUrl.indexOf("&" + name + "="); // 判断是否存在要设置的参数 if (index >= 0) { // 获取要设置参数的前面的参数 var temp1 = paramUrl.substring(0, index); // 获取要设置参数的后面的参数 var temp2 = paramUrl.substring(index + ("&" + name + "=").length); // 获取要设置的参数后面的参数开始的索引 index = temp2.indexOf("&"); // 判断后面是否有参数 if (index >= 0) { // 有参数则构造新的URL地址 return baseUrl + temp1 + "&" + name + "=" + value + temp2.substring(index); } else { // 没参数则构造新的URL地址 return baseUrl + temp1 + "&" + name + "=" + value; } } else { // 不存在参数则构造新的URL地址 return url + "&" + name + "=" + value; } } } else { // 原URL地址中没参数则直接构成新的URL地址 return url + "?" + name + "=" + value; } }