iOS網絡開發-打造本身的視頻客戶端

一.展現實現

效果web

    

 

客戶端:                                      服務器端:算法

          

二.建立表

 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 )

  

添加數據json

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表信息框架

這是比較簡單容易理解的方式,可是字段多的話就很不實用。ide

//查詢視頻資源
        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>

看下結果

接下來把項目部署在IIS服務器上便可使用,如何部署我這就很少說了,能夠查一下百度

 

 附件:忘記保存了,這裏用到一個工具

WSDL2ObjC-0.6.zip

 Parse WSDL後稍等15秒左右出現Finish!查看導入目錄

將生成的全部文件放置在wsdl2objc文件夾導入項目中

嘗試編譯出現錯誤以下:1."libxml/tree.h" file not found

解決辦法:

連接libxml2.2dylib庫

TARGETS -> Build Phases -> Linking Binary With Libraries-> libxml2.2dylib

TARGETS -> Build Settings -> Search Paths-> Header Search Paths,設置「/usr/include/libxml2」

TARGETS -> Build Phases -> Compile Sources  將Service.m,USAddition.m,NSDate+ISO8601Unparsing.m,NSDate+ISO8601Parsing.m

文件 設置不使用ARC   -fno-objc-arc

手動ARC設置方法以下:

1.在Compiler Flags一列加上-fno-objc-arc就表示禁止這個.m文件的ARC

2.在Compiler Flags一列加上-fobjc-arc就表示開啓這個.m文件的ARC

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>

 

 

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
相關文章
相關標籤/搜索