转载

iOS网络开发-打造自己的视频客户端

一.展示实现

效果

iOS网络开发-打造自己的视频客户端 iOS网络开发-打造自己的视频客户端

客户端:                                      服务器端:

iOS网络开发-打造自己的视频客户端 iOS网络开发-打造自己的视频客户端

二.创建表

 1 create table CourseVideo  2 (  3     VideoID int IDENTITY(1,1)  NOT NULL,      4     CourseID int NOT NULL,   5     VideoName varchar(500)  NULL,    6     VideoPath [varchar](100) NULL,  7     VideoImage [varchar](200) NULL,  8     VideoDes [varchar](200) NULL,  9    VideoLength int NULL, 10     primary key(VideoID) 11 )



添加数据

INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (1, 1, N'数组1_为什么要使用数组.mp4', N'CourseVideo/1.mp4', N'CourseImage/1.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (2, 1, N'数组2_什么是数组', N'CourseVideo/2.mp4', N'CourseImage/2.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (3, 1, N'数组3_数组的分类及特点', N'CourseVideo/3.mp4', N'CourseImage/3.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (4, 1, N'数组4:一维数组的声明', N'CourseVideo/4.mp4', N'CourseImage/4.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (5, 1, N'数组5:一维数组的初始化', N'CourseVideo/5.mp4', N'CourseImage/5.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (6, 1, N'数组6:一维数组的访问(引用)', N'CourseVideo/6.mp4', N'CourseImage/6.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (7, 1, N'数组7:数组的算法:查找', N'CourseVideo/7.mp4', N'CourseImage/7.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (8, 1, N'数组8:数组的算法:排序 (1)', N'CourseVideo/8.mp4', N'CourseImage/8.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (9, 1, N'数组09:二维数组的声明', N'CourseVideo/9.mp4', N'CourseImage/9', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (10, 1, N'数组10:二维数组的初始化', N'CourseVideo/10.mp4', N'CourseImage/10.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (11, 1, N'数组11:二维数组的访问', N'CourseVideo/11.mp4', N'CourseImage/11.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (12, 1, N'数组12:多维数组简介', N'CourseVideo/12.mp4', N'CourseImage/12.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (13, 1, N'数组13:C语言中的字符串', N'CourseVideo/13.mp4', N'CourseImage/13.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (14, 1, N'数组14:字符数组', N'CourseVideo/14.mp4', N'CourseImage/14.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (15, 1, N'数组15:字符串的输入输出', N'CourseVideo/15.mp4', N'CourseImage/15.png', NULL) GO INSERT [dbo].[CourseVideo] ([VideoID], [CourseID], [VideoName], [VideoPath], [VideoImage], [VideoDes]) VALUES (16, 1, N'数组16:字符串处理函数', N'CourseVideo/16.mp4', N'CourseImage/16.jpg', NULL) GO

记得视频路径勿加中文,否则视频播放不出来

三.搭建WebService服务器

1.DatableToList.cs文件用于DataTable转换List<T>

public class DatableToList   {   public static List<T> ConvertToList<T>(DataTable dt) where T : new()   {    //定义集合    List<T> ts = new List<T>();    //获得此模型的类型    Type type = typeof(T);    //定义一个临时变量    string tempName = string.Empty;    //便利DataTable数据行    foreach (DataRow dr in dt.Rows)    {     T t = new T();     //获得此模型的公共属性     PropertyInfo[] propertys = t.GetType().GetProperties();     //遍历该对象的所有属性     foreach(PropertyInfo pi in propertys)     {      tempName = pi.Name;//将属性名称赋值给临时变量      //检查DataTable是否包含此列(列名==对象的属性名)        if (dt.Columns.Contains(tempName))      {       // 判断此属性是否有Setter       if (!pi.CanWrite) continue;//该属性不可写,直接跳出       //取值       object value = dr[tempName];       //如果非空,则赋给对象的属性       if (value != DBNull.Value)        pi.SetValue(t, value, null);      }     }      //对象添加到泛型集合中     ts.Add(t);    }    return ts;   }  } 

2.创建Model类库

CourseVideo.cs类

public  class CourseVideo {  private int videoID;  public int VideoID  {   get { return videoID; }   set { videoID = value; }  }  private int courseID;  public int CourseID  {   get { return courseID; }   set { courseID = value; }  }  private String videoName;  public String VideoName  {   get { return videoName; }   set { videoName = value; }  }  private String videoPath;  public String VideoPath  {   get { return videoPath; }   set { videoPath = value; }  }  private String videoImage;  public String VideoImage  {   get { return videoImage; }   set { videoImage = value; }  } 
    private int videoLength;
      public int VideoLength         {             get { return videoLength; }             set { videoLength = value; }         }
}

3.创建Dal类库

CourseVideoDal.cs类

查询CourseVideo表信息

这是比较简单容易理解的方式,但是字段多的话就很不实用。

//查询视频资源 public List<CourseVideo> Select() {  List<CourseVideo> list = new List<CourseVideo>();  DataTable dt = new DataTable();  CourseVideo model = null;  DataBase db = new DataBase();  String comstr = "select VideoID,CourseID,VideoName,VideoPath,VideoImage,VideoLength from CourseVideo";  dt = db.GetDataTable(comstr);  for (int i = 0; i < dt.Rows.Count;i++ )  {   model = new CourseVideo();   model.VideoID = Convert.ToInt32(dt.Rows[i][0]);   model.CourseID = Convert.ToInt32(dt.Rows[i][1]);   model.VideoName = dt.Rows[i][2].ToString();   model.VideoPath = dt.Rows[i][3].ToString();   model.VideoImage = dt.Rows[i][4].ToString();
model.VideoLength = Convert.ToInt32(dt.Rows[i][5]);
list.Add(model);
}
return list;
}

之前新建的DatableToList.cs类文件就可以用到了,使用泛型将DataTable数据转换为List<T>

泛型之前一直没机会用到,于是自己百度学习了一下,封装好DatableToList文件后,很好的提高代码

了质量,更方便使用。

//使用泛型 查询视频资源 public List<CourseVideo> Select2() {  List<CourseVideo> list = new List<CourseVideo>();  DataTable dt = new DataTable();  DataBase db = new DataBase();  String comstr = "select VideoID,CourseID,VideoName,VideoPath,VideoImage,VideoLength from CourseVideo";  dt = db.GetDataTable(comstr);  list = DatableToList.ConvertToList<CourseVideo>(dt);  return list; } 

4.新建Web 服务

只需要在App_Code文件夹下找到Service.cs添加

4.1返回json格式

添加命名空间:

using System.Web.Script.Services;using System.Web.Script.Serialization;

还有在方法前面声明

[WebMethod(Description = " json查询视频资源 " )]

 [ScriptMethod(ResponseFormat = ResponseFormat.Json)]

[WebMethod(Description = "json查询视频资源")]  [ScriptMethod(ResponseFormat = ResponseFormat.Json)]  public String VideoSelect()  {   return new JavaScriptSerializer().Serialize(courseVideoDal.Select());   //   return dal.Select();   } 

4.1返回xml格式

[WebMethod(Description = "xml查询视频资源")]  public List<CourseVideo> xmlVideoSelect() { return courseVideoDal.Select(); }

设置外部访问需要在Web.config添加节点:

<webServices>   <protocols>     <add name="HttpSoap" />     <add name="HttpPost" />     <add name="HttpGet" />     <add name="Documentation" />   </protocols> </webServices> 

看下结果 iOS网络开发-打造自己的视频客户端

iOS网络开发-打造自己的视频客户端

接下来把项目部署在IIS服务器上即可使用,如何部署我这就不多说了,可以查一下百度

5.创建数据模型

lmjVideo.h文件

//视频ID @property (assign,nonatomic) int ID;  //视频名称 @property (copy,nonatomic) NSString *name;  //视频长度 @property (assign,nonatomic) int length;  //视频图片 @property (copy,nonatomic) NSString *image;  //视频链接 @property (copy,nonatomic) NSString *url;  + (instancetype)videoWithDict:(NSDictionary *)dict;

lmjVideo.m文件

+(instancetype)videoWithDict:(NSDictionary *)dict {  lmjVideo *video = [[self alloc] init];  video.name = dict[@"VideoName"];  video.image = dict[@"VideoImage"];  video.url = dict[@"VideoPath"];  video.length = [dict[@"VideoLength"] intValue];  video.ID = [dict[@"VideoID"] intValue];  return video;   // [video setValuesForKeysWithDictionary:dict]; // KVC方法使用前提: 字典中的所有key 都能在 模型属性 中找到   } 

自定义cell,对cell内部数据处理的封装

lmjVideoCell.h文件

文件

@class lmjVideo; @interface lmjVideoCell : UITableViewCell  @property (nonatomic,strong) lmjVideo *video; + (instancetype)cellWithTableView:(UITableView *)tableView;

lmjVideoCell.m文件

#import "lmjVideoCell.h" #import "lmjVideo.h" #import "UIImageView+WebCache.h" #import "UIView+Extension.h" @interface lmjVideoCell() @property (nonatomic,weak) UIView *driver; @end @implementation lmjVideoCell + (instancetype)cellWithTableView:(UITableView *)tableView {  static NSString *ID = @"video";  lmjVideoCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];  if (!cell)  {   cell = [[lmjVideoCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];  }  return cell; } - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {  self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];  if (self) {   UIView *driver = [[UIView alloc] init];   driver.backgroundColor = [UIColor lightGrayColor];   driver.alpha = 0.2;   [self.contentView addSubview:driver];   self.driver = driver;  }  return self; } - (void)setVideo:(lmjVideo *)video {  _video = video;  self.textLabel.text = video.name;  self.detailTextLabel.text = [NSString stringWithFormat:@"时长:%d分钟",video.length];  NSString *imageUrl = [NSString stringWithFormat:@"http://180.84.33.156:8882/%@",video.image];  [self.imageView setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"placeholder"]]; } - (void)layoutSubviews {  [super layoutSubviews];  //调整子控件的frame  CGFloat imageX = 10;  CGFloat imageY = 10;  CGFloat imageH = self.height - 2 * imageY;  CGFloat imageW = imageH * 200 / 112;  self.imageView.frame = CGRectMake(imageX, imageY, imageW, imageH);  self.textLabel.x = CGRectGetMaxX(self.imageView.frame) + 10;  self.detailTextLabel.x = self.textLabel.x;  CGFloat driverH = 1;  CGFloat driverY = self.height - driverH;  CGFloat driverW = self.width;  self.driver.frame = CGRectMake(0, driverY, driverW, driverH); } 

分类

UIView+Extension.h文件

添加一个UIView的分类,直接修改UI控件的x值

@property (nonatomic,assign) CGFloat x; @property (nonatomic,assign) CGFloat y; @property (nonatomic,assign) CGFloat width; @property (nonatomic,assign) CGFloat height;

UIView+Extension.m文件

#import "UIView+Extension.h" @implementation UIView (Extension) - (void)setX:(CGFloat)x {  CGRect frame = self.frame;  frame.origin.x = x;  self.frame = frame; } - (CGFloat)x {  return self.frame.origin.x; } - (void)setY:(CGFloat)y {  CGRect frame = self.frame;  frame.origin.y = y;  self.frame = frame; } - (CGFloat)y {  return self.frame.origin.y; } - (void)setWidth:(CGFloat)width {  CGRect frame = self.frame;  frame.size.width = width;  self.frame = frame; } - (CGFloat)width {  return self.frame.size.width; } - (void)setHeight:(CGFloat)height {  CGRect frame = self.frame;  frame.size.height = height;  self.frame = frame; }
- (CGFloat)height { return self.frame.size.height; } @end

实现“视屏列表界面只支持竖屏方向

自定义lmjNavigationController控制器,其继承自UINavigationController

   UIInterfaceOrientationMaskPortrait:竖屏(正常)    UIInterfaceOrientationMaskPortraitUpsideDown:竖屏(上下颠倒)    UIInterfaceOrientationMaskLandscapeLeft:横屏向左    UIInterfaceOrientationMaskLandscapeRight:横屏向右    UIInterfaceOrientationMaskLandscape:横屏(左右都支持)    UIInterfaceOrientationMaskAll:所有都支持    

lmjNavigationViewController.m

#import "lmjNavigationViewController.h"  @interface lmjNavigationViewController ()  @end  @implementation lmjNavigationViewController  //控制当前控制器支持那些方向  -(NSUInteger)supportedInterfaceOrientations {
//竖屏
return UIInterfaceOrientationMaskPortrait; } @end

自定义lmjMoviePlayerViewController控制器,继承MPMoviePlayerViewController

导入MediaPlayer.framework框架,lmjMoviePlayerViewController.h在添加头文件

#import <MediaPlayer/MediaPlayer.h>

iOS网络开发-打造自己的视频客户端

lmjMoviePlayerViewController.m

#import "lmjMoviePlayerViewController.h" @interface lmjMoviePlayerViewController () @end @implementation lmjMoviePlayerViewController - (void)viewDidLoad {  [super viewDidLoad];  // 移除程序进入后台的通知  [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; } #pragma mark - 实现这个方法来控制屏幕方向 /**  *  控制当前控制器支持哪些方向  *  返回值是UIInterfaceOrientationMask*  */ - (NSUInteger)supportedInterfaceOrientations {  return UIInterfaceOrientationMaskLandscape; }

@end

6.主控制器文件代码:

需要注意的是,视频播放的文件路径勿加中文,否则视频不能播放

// //  lmjViewController.m //  橙子视频客户端 // //  Created by lmj on 15-6-24. //  Copyright (c) 2015年 lmj. All rights reserved. //  #import "lmjViewController.h" #import "MBProgressHUD+MJ.h" #import "lmjVideo.h" #import "UIImageView+WebCache.h" #import "lmjMoviePlayerViewController.h" #import "lmjVideoCell.h" #import "Service.h" #define strUrl @"http://180.84.33.156:8882" @interface lmjViewController () //所有视频的集合 @property (nonatomic,strong) NSArray *videos; @end @implementation lmjViewController - (void)viewDidLoad {  [super viewDidLoad];  [MBProgressHUD showMessage:@"正在加载视频信息..."];  NSString *result;  NSData *data;  ServiceSoap *binding = [Service ServiceSoap];  Service_VideoSelect  *request = [[Service_VideoSelect  alloc] init];  ServiceSoap12Response *response = [binding  VideoSelectUsingParameters:request];  for(id mine in response.bodyParts){   if([mine isKindOfClass:[Service_VideoSelectResponse class]])   {    //   [request  release];    [MBProgressHUD hideHUD];    result = [mine VideoSelectResult];    data = [result dataUsingEncoding:NSUTF8StringEncoding];    if(data)    {     //  NSLog(@"data----%@",data);     NSArray *array =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];     NSMutableArray *videos = [NSMutableArray array];     for (NSDictionary *dict in array) {     lmjVideo *video = [lmjVideo videoWithDict:dict];     [videos addObject:video];     NSLog(@"%@",video.url);     }     self.videos = videos;     [self.tableView reloadData];    }    else{     [MBProgressHUD showError:@"网络繁忙"];    }   //  NSLog(@"ns----%@",ns);    //  NSDictionary *dict= [NSJSONSerialization JSONbjectWithData:data  options:NSJSONReadingAllowFragmentS error:nil];       }  } } #pragma mark -数据源 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {  return self.videos.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {  lmjVideoCell *cell = [lmjVideoCell cellWithTableView:tableView];  cell.video = self.videos[indexPath.row];  return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {  return 70; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  lmjVideo *video = self.videos[indexPath.row];  //播放视频  NSLog(@"%@",video.url);  NSString *videoUrl = [NSString stringWithFormat:@"http://180.84.33.156:8882/%@",video.url];  lmjMoviePlayerViewController *playerVc = [[lmjMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:videoUrl]];  [self presentMoviePlayerViewControllerAnimated:playerVc] ;   //全拼播放 } @end 
正文到此结束
Loading...