首页 » 技术分享 » C#网络电视精灵系统

C#网络电视精灵系统

 

1.XML文件

*存储频道信息

<?xml version="1.0" encoding="utf-8" ?>
<TVChannels>
	<Channel>
		<channelType>TypeA</channelType> <!--频道类型-->
		<tvChannel>北京电视台</tvChannel> <!--频道名称-->
		<path>files/北京电视台.xml</path>  <!--频道对应XML文件的本地路径-->
	</Channel>
	<Channel>
		<channelType>TypeB</channelType>
		<tvChannel>凤凰卫视</tvChannel>
		<path>files/凤凰卫视.xml</path>
	</Channel>
</TVChannels>
	

*北京电视台

<?xml version="1.0" encoding="utf-8" ?>
<typeA version =" 1.0">
    <channelName>北京电视台</channelName>
	<tvProgramTable>
		<tvProgram>
			<playTime>2013-9-29 06:02</playTime> <!--节目播出时间-->
			<meridien>早间档</meridien> <!--时段-->       
			<programName>重播:国际双行线</programName> <!--节目名称-->
			<path>c:\a.wma</path>         <!--视频路径-->
		</tvProgram>
        <tvProgram>
			<playTime>2013-9-29 07:00</playTime> <!--节目播出时间-->
			<meridien>早间档</meridien> <!--时段-->
			<programName>北京您早</programName> <!--节目名称-->
			<path>C:\New Stories (Highway Blues).wma</path>         <!--视频路径-->
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 09:02</playTime> <!--节目播出时间-->
			<meridien>早间档</meridien> <!--时段-->   
			<programName>重播《红星剧场》32集剧:勇者无敌(31)</programName> <!--节目名称-->
			<path>**</path>         <!--视频路径-->
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 09:58</playTime>
			<meridien>早间档</meridien>
			<programName>重播《红星剧场》32集剧:勇者无敌(32)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 11:15</playTime>
			<meridien>午间档</meridien>
			<programName>重播:专题片:我爱你,中国(14)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 11:58</playTime>
			<meridien>午间档</meridien>
			<programName>身边</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 12:30</playTime>
			<meridien>午间档</meridien>
			<programName>特别关注</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 13:05</playTime>
			<meridien>午间档</meridien>
			<programName>天下天天谈</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 13:40</playTime>
			<meridien>午间档</meridien>
			<programName>《玫瑰剧场》55集剧:闯关东中篇(21)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 14:32</playTime>
			<meridien>午间档</meridien>
			<programName>《玫瑰剧场》55集剧:闯关东中篇(22)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 15:27</playTime>
			<meridien>下午档</meridien>
			<programName>《玫瑰剧场》55集剧:闯关东中篇(23)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 16:19</playTime>
			<meridien>下午档</meridien>
			<programName>《玫瑰剧场》55集剧:闯关东中篇(24)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 17:31</playTime>
			<meridien>下午档</meridien>
			<programName>法治进行时</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 18:00</playTime>
			<meridien>晚间档</meridien>
			<programName>新闻晚高峰</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 18:30</playTime>
			<meridien>晚间档</meridien>
			<programName>北京新闻</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 18:56</playTime>
			<meridien>晚间档</meridien>
			<programName>天气预报</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 19:00</playTime>
			<meridien>晚间档</meridien>
			<programName>转播CCTV新闻联播</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 19:31</playTime>
			<meridien>晚间档</meridien>
			<programName>看气象</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 19:40</playTime>
			<meridien>晚间档</meridien>
			<programName>专题片:我爱你,中国(15)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 20:22</playTime>
			<meridien>晚间档</meridien>
			<programName>《爸妈都是老党员》首播庆典</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 21:21</playTime>
			<meridien>晚间档</meridien>
			<programName>《红星剧场》38集剧:咱爸咱妈六十年(1)</programName>
			<path>**</path>
		</tvProgram>
		<tvProgram>
			<playTime>2013-9-29 23:25</playTime>
			<meridien>晚间档</meridien>
			<programName>重播文艺:花样年华歌舞大赛(5)</programName>
			<path>**</path>
		</tvProgram>
	</tvProgramTable>
</typeA>


*凤凰卫视

<?xml version="1.0" encoding="utf-8" ?>
<typeB version =" 1.0">
	<ProgramList>
		<Program>
			<playTime>2013-9-29 01:30</playTime>  <!--播出时间-->
			<name>金龙鱼凤凰剧场:李算(9)</name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 02:10</playTime>  <!--播出时间-->
			<name>非凡人物论成功(713)</name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 02:15</playTime>  <!--播出时间-->
			<name>有报天天读(28/09/09) </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 02:40</playTime>  <!--播出时间-->
			<name>娱乐大风暴(682) </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 03:15</playTime>  <!--播出时间-->
			<name>上海新长宁集团特约之2013中华小姐环球大赛-美丽前奏(41) </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 03:20</playTime>  <!--播出时间-->
			<name>完全时尚手册:天桥云裳(632)  </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 03:40</playTime>  <!--播出时间-->
			<name>东风康明斯凤凰冲击播:天力士特约之今日看世界(39)  </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 04:25</playTime>  <!--播出时间-->
			<name>音乐中国风(442)  </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 04:35</playTime>  <!--播出时间-->
			<name>维维健康新概念(193) </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 04:40</playTime>  <!--播出时间-->
			<name>红牛凤凰全球连线(28/09/09) </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 05:05</playTime>  <!--播出时间-->
			<name>红云红河时事开讲(28/09/09)  </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
		<Program>
			<playTime>2013-9-29 05:30</playTime>  <!--播出时间-->
			<name>别巡检调查队(34)(R) </name>          <!--节目名称-->
			<path>**</path>          <!--节目视频的本地路径-->
		</Program>
	</ProgramList>
</typeB>

2.分类

*抽象类ChannelBase存储频道基本信息,定义抽象方法Fetch()解析频道节目单信息

 public abstract  class ChannelBase
    {
        #region 属性

      
        /// <summary>
        /// 频道名称
        /// </summary>
        private string channelName;
        public string ChannelName
        {
            get { return channelName; }
            set { channelName = value; }
        }
        /// <summary>
        /// 频道路径
        /// </summary>
        private string path;
        public string Path
        {
            get { return path; }
            set { path = value; }
        }
        /// <summary>
        /// 节目列表
        /// </summary>
        private List<TvProgram> programList;
        public List< TvProgram> ProgramList
        {
            get { return programList; }
            set { this.programList = value; }
        }
     #endregion

        public abstract void Fetch();
        
    }

*电视节目类

 /// <summary>
    /// 节目对象
    /// </summary>
    public class TvProgram
    {
        #region 属性

        /// <summary>
        /// 播出时间
        /// </summary>
        private DateTime playTime;
        public DateTime PlayTime
        {
            get { return playTime; }
            set { playTime = value; }
        }
        /// <summary>
        /// 时段
        /// </summary>
        private string median;
        public string Median
        {
            get { return median; }
            set { median = value; }
        }
        /// <summary>
        /// 名称
        /// </summary>
        private string programName;
        public string ProgramName
        {
            get { return programName; }
            set { programName = value; }
        }
        /// <summary>
        /// 文件路径
        /// </summary>
        private string filePath;
        public string FilePath
        {
            get { return filePath; }
            set { filePath = value; }
        }
        #endregion

    }

*TypeA类型频道类

    /// <summary>
    /// TypeA类型节目单解析

    /// </summary>
    public  class TypeAChannel:ChannelBase
    {
        /// <summary>
        /// 多态,覆盖父类的获取频道列表方法

        /// </summary>
        public override void Fetch()
        {
            //获取频道列表
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                //加载频道节目单文件

                xmlDoc.Load(Path);
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件加载失败:" + ex.Message);
                return;
            }
            XmlElement elem = xmlDoc.DocumentElement;
            if (ProgramList == null)
            {
                ProgramList = new List<TvProgram>();
            }
            foreach (XmlNode node in elem.ChildNodes)
            {
                if (node.Name == "tvProgramTable")
                {
                    foreach (XmlNode subnode in node.ChildNodes)
                    {
                        TvProgram program = new TvProgram();
                        program.PlayTime = DateTime.Parse(subnode["playTime"].InnerText);
                        program.Median = subnode["meridien"].InnerText;
                        program.ProgramName = subnode["programName"].InnerText;
                        program.FilePath = subnode["path"].InnerText;

                        this.ProgramList.Add(program);
                    }
                }
            } 
        }
    }

*TypeB类型频道类



 /// <summary>
    /// TypeB类型节目单解析

    /// </summary>
    public class TypeBChannel : ChannelBase
    {
        /// <summary>
        /// 多态,覆盖父类方法,获取TypeBChannel的节目列表

        /// </summary>
        public override void Fetch()
        {
            //获取节目列表
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.Load(Path);
            }
            catch (Exception ex)
            {
                Console.WriteLine("文件加载失败:" + ex.Message);
                return;
            }
            XmlElement elem = xmlDoc.DocumentElement;
            if (ProgramList == null)
            {
                ProgramList = new List<TvProgram>();
            }
            foreach (XmlNode node in elem.ChildNodes[0])//【0】第一个节点

            {
                TvProgram programe = new TvProgram();
                programe.PlayTime = DateTime.Parse(node["playTime"].InnerText);
                programe.Median = "";

                programe.ProgramName = node["name"].InnerText;
                programe.FilePath = node["path"].InnerText;

                this.ProgramList.Add(programe);
            }
        }
    }

*channelManager类:读取xml文件,加载所有频道列表.根据频道类型创建"工厂"


 public class ChannelManager
    {
     
        /// <summary>
        /// 频道文件路径
        /// </summary>
        private string channelPath ="files/FullChannels.xml";
    
        /// <summary>
        /// 全部频道
        /// </summary>
        private Dictionary<string, ChannelBase> fullChannel=new Dictionary<string,ChannelBase>();
        public Dictionary<string, ChannelBase> FullChannel
        {
            get 
            { 
                return fullChannel; 
            }
        }

        //持久化信息
        private SavingInfo seria = new SavingInfo();
        public SavingInfo Seria
        {
            get { return seria; }

        }

        /// <summary>
        /// 启动程序时,读取FullChannels.xml,加载所有频道列表

        /// </summary>
        public void LoadChannel()
        {
            //预处理集合,防止被重复加载数据
            try
            {
                fullChannel.Clear();
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(channelPath);
                XmlElement xmlRoot = xmlDoc.DocumentElement;
                foreach (XmlNode node in xmlRoot.ChildNodes)
                {
                    //根据频道类型创建对象
                    ChannelBase channel =CreateChannel(node["channelType"].InnerText);
                    channel.ChannelName = node["tvChannel"].InnerText;
                    channel.Path = node["path"].InnerText;
                    this.fullChannel.Add(channel.ChannelName, channel);
                }

            }
            catch
            {
                throw new Exception("数据加载错误!");
            }

            
        }

        public  ChannelBase CreateChannel(string type)
        {
            ChannelBase channel = null;
            switch (type)
            {
                case "TypeA":
                    channel = new TypeAChannel();
                    break;
                case "TypeB":
                    channel = new TypeBChannel();
                    break;
                default:
                    break;
            }
            return channel;
        }


        //保存定制频道信息的文本文件名称
        private string saveFileName = @"files\save";
        /// <summary>
        /// 将我的电台信息存储到文本文件之中
        /// 要解决中文乱码问题
        /// </summary>
        public void SaveAsTxt()
        {
            try
            {
                FileStream fs = new FileStream(saveFileName + ".txt", FileMode.Create);
                StreamWriter writer = new StreamWriter(fs, Encoding.GetEncoding("GB2312"));
                string type = "";
                for (int index = 0; index < this.seria.MyFavor.Count; index++)
                {
                    ChannelBase channel = this.seria.MyFavor[index];
                    if (channel is TypeBChannel)
                    {
                        type = "TypeB";
                    }
                    else
                    {
                        type = "TypeA";
                    }
                    writer.WriteLine(type
                        + "|" + channel.ChannelName
                        + "|" + channel.Path);
                }

                writer.WriteLine("End of my Favor");
                writer.Close();
                fs.Close();

            }
            catch (Exception ex)
            {
                MessageBox.Show("写入文件失败:" + ex.ToString());
            }
        }

        /// <summary>
        /// 从文本文件之中读取"我的电台"信息

        /// </summary>
        public void LoadFromText()
        {
            //#region 存在性判断

            if (!File.Exists(@"files\save.txt"))
            {//不存在则不再处理
                return;
            }
            //#endregion

            try
            {
                StreamReader reader = new StreamReader(saveFileName + ".txt", Encoding.GetEncoding("GB2312"));
                string line = reader.ReadLine();
                string[] propertyValues;
                ChannelBase channel = null;
               
                while (line.Trim() != "End of my Favor")
                {

                    propertyValues = line.Split('|');
                    channel = CreateChannel(propertyValues[0]);

                    channel.ChannelName = propertyValues[1];
                    channel.Path = propertyValues[2];
                    this.seria.MyFavor.Add(channel);
                    line = reader.ReadLine();
                }
                reader.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("文件操作异常:" + ex.Message);
            }
        }
    }

*持久化信息类SavingInfo

  //持久化信息类
    public class SavingInfo
    {
        public SavingInfo()
        {
            this.myFavor = new List<ChannelBase>();
        }
        #region 属性


        /// <summary>
        /// 我的收藏
        /// </summary>
        private List<ChannelBase> myFavor;
        public List<ChannelBase> MyFavor
        {
            get
            {
                if (myFavor == null)
                {
                    return new List<ChannelBase>();
                }
                else
                {
                    return myFavor;
                }
            }
            set { myFavor = value; }
        }
        #endregion

    }

3.主窗体

*电视台初始化

/// <summary>
        /// 管理器类
        /// </summary>
        private ChannelManager myManager = new ChannelManager();

        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 电视台初始化
        /// </summary>
        private void InitChannel()
        {
            //加载所有频道信息
            myManager.LoadChannel();

            //加载用户定制的频道信息
            myManager.LoadFromText();

            //刷新TreeView显示
            UpdateTreeView();

        }

 /// <summary>
        /// 窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.SetVisible(true);
            this.InitChannel();

        }

 /// <summary>
        /// 控制DataGridView和listView的显示

        /// </summary>
        /// <param name="boolInfo"></param>
        private void SetVisible(bool boolInfo)
        {
            this.dgvProgList.Visible = boolInfo;
        }


*刷新频道列表


  private void UpdateTreeView()
        {
            //清空所有节点

            this.tvChannel.Nodes.Clear();

            //初始化根结点
            TreeNode nodeFirstLevel = new TreeNode("我的电视台");
            nodeFirstLevel.ImageIndex = 0;
            this.tvChannel.Nodes.Add(nodeFirstLevel);
            nodeFirstLevel = new TreeNode("所有电视台");
            this.tvChannel.Nodes.Add(nodeFirstLevel);

            //加载“所有电视台”

            foreach (ChannelBase dicOne in myManager.FullChannel.Values)
            {
                TreeNode node = new TreeNode();
                node.Text = dicOne.ChannelName;
                node.Tag = dicOne;
                node.ImageIndex = 1;
                this.tvChannel.Nodes[1].Nodes.Add(node);

            }

            //加载“我的电视台”

            foreach (ChannelBase dicOne in myManager.Seria.MyFavor)
            {
                TreeNode node = new TreeNode();
                node.Text = dicOne.ChannelName;
                node.Tag = dicOne;
                node.ImageIndex = 1;
                this.tvChannel.Nodes[0].Nodes.Add(node);
            }

            //展开所有节点

            tvChannel.ExpandAll();
        }


*将一个电台添加到我的电台中


 private void tsmAddToFavor_Click(object sender, EventArgs e)
        {
            TreeNode node = this.tvChannel.SelectedNode;
            //没有选中任何节点,返回

            if (node == null)
            {
                return;
            }
            ChannelBase ch = (ChannelBase)node.Tag;
            //保证不重复

            foreach (TreeNode nodeItem in this.tvChannel.Nodes[0].Nodes)
            {
                if (nodeItem.Text.Trim() == node.Text.Trim())
                {
                    return;//发现“我的收藏夹”中有这个电台,就退出,不再执行添加工作。

                }
            }
            this.myManager.Seria.MyFavor.Add(ch);
            this.UpdateTreeView();
        }


右键单击树型菜单,控制右键菜单的菜单

即“所有电视台”的子节点的右键中只显示“加入到我的电台”
而“我的电视台”的子节点的右键只能显示"删除"

private void tvChannel_MouseClick(object sender, MouseEventArgs e)
        {
            //只处理右键事件

            TreeNode node = this.tvChannel.SelectedNode;
            if (node != null && node.Level != 0)//有节点被选中且不是顶级节点
            {
                //这句代码保证右键点击树的时候,那个节点处于选中状态

                if (node.Parent.Text == "所有电视台")
                {
                    //使"加入到我的电台"这个菜单项可见

                    cmenuRight.Items[1].Visible = false;
                    cmenuRight.Items[0].Visible = true;
                }
                else
                {
                    //使“删除”菜单项可见
                    cmenuRight.Items[0].Visible = false;
                    cmenuRight.Items[1].Visible = true;
                }
            }
            else
            {
                cmenuRight.Items[1].Visible = false;
                cmenuRight.Items[0].Visible = false;
            }
        }


 private void TMenuItemDel_Click(object sender, EventArgs e)
        {
            TreeNode node = this.tvChannel.SelectedNode;
            //没有选中任何节点,返回
            if (node == null)
            {
                return;
            }
            ChannelBase ch = (ChannelBase)node.Tag;

            this.myManager.Seria.MyFavor.Remove(ch);
            this.UpdateTreeView();
        }

树形菜单选项改变事件:改变频道,加载选中频道的节目信息

private void tvChannel_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //控制DataGridView的显示

            this.SetVisible(true);
            //e.Node选中的节点

            if (e.Node.Level != 0)
            {
                ChannelBase ch = (ChannelBase)e.Node.Tag;
                if (ch.ProgramList != null)
                {
                    ch.ProgramList.Clear();//清除当前节目单

                }
                ch.Fetch(); //读取节目单

                this.dgvProgList.DataSource = ch.ProgramList; //绑定到数据展示控件显示

                this.dgvProgList.Tag = ch.ChannelName; //将当前Dgv的Tag属性设为频道的名称
            }
        }

转载自原文链接, 如需删除请联系管理员。

原文链接:C#网络电视精灵系统,转载请注明来源!

0