From: Călin-Andrei Burloiu Date: Tue, 14 Feb 2012 14:58:37 +0000 (+0200) Subject: uploading works, but AV info is not automatically detected and video activation featu... X-Git-Url: http://p2p-next.cs.pub.ro/gitweb/?p=living-lab-site.git;a=commitdiff_plain;h=8b8928b4cc25af9867c397ba5ef4b1129a8df5b5 uploading works, but AV info is not automatically detected and video activation features are not implemented --- diff --git a/application/config/content_ingestion.php b/application/config/content_ingestion.php new file mode 100644 index 0000000..a21310f --- /dev/null +++ b/application/config/content_ingestion.php @@ -0,0 +1,98 @@ +'ogg', +| 'extension'=>'ogv', +| 'audio_codec'=>'vorbis', +| 'audio_bit_rate'=>'128k', +| 'audio_sampling_rate'=>44100, +| 'audio_channels'=>2, +| 'video_codec'=>'theora', +| 'video_bit_rate'=>'768k', +| 'video_frame_rate'=>25, +| 'video_height'=>600 +| ) +| ); +| +| For a list of available containers and audio / video codecs see CIS +| documentation. The video_height parameter is a desired height resolution. +| It may be lower if the uploaded video has a lower resolution. +| +*/ +// +$config['formats'] = array( + array( + 'container'=>'ogg', + 'extension'=>'ogv', + 'audio_codec'=>'vorbis', + 'audio_bit_rate'=>'128k', + 'audio_sampling_rate'=>44100, + 'audio_channels'=>2, + 'video_codec'=>'theora', + 'video_bit_rate'=>'768k', + 'video_frame_rate'=>25, + 'video_height'=>600 + ), + array( + 'container'=>'ogg', + 'extension'=>'ogv', + 'audio_codec'=>'vorbis', + 'audio_bit_rate'=>'192k', + 'audio_sampling_rate'=>44100, + 'audio_channels'=>2, + 'video_codec'=>'theora', + 'video_bit_rate'=>'1536k', + 'video_frame_rate'=>25, + 'video_height'=>1080 + ) +); + +/* +|-------------------------------------------------------------------------- +| Thumnail images count +|-------------------------------------------------------------------------- +| +| Number of thumbnail images for a video asset. +| +*/ +$config['thumbs_count'] = 4; + +/* +|-------------------------------------------------------------------------- +| Eliminate Duplicate Resolutions +|-------------------------------------------------------------------------- +| +| Eliminate consecutive formats with the same resolution after processing +| them. +| +*/ +$config['elim_dupl_res'] = TRUE; \ No newline at end of file diff --git a/application/config/p2p-tube.php b/application/config/p2p-tube.php index bcbe0f5..20ba114 100644 --- a/application/config/p2p-tube.php +++ b/application/config/p2p-tube.php @@ -1,6 +1,6 @@ setOptions(array('cookies' => array('lang' => 'de'))); - $r->addPostFields(array('user' => 'mike', 'pass' => 's3c|r3t')); - $r->addPostFile('image', 'profile.jpg', 'image/jpeg'); - try - { - echo $r->send()->getBody(); - } - catch (HttpException $ex) - { - echo $ex; - } + var_dump($this->session->userdata('user_id')); } /** @@ -104,13 +96,22 @@ class Video extends CI_Controller { public function upload() { + $user_id = $this->session->userdata('user_id'); + + // Action not possible if an user is not logged in. + if (!$user_id) + { + $this->load->helper('message'); + show_error_msg_page($this, + $this->lang->line('ui_msg_login_restriction')); + return; + } + $this->load->library('form_validation'); $this->form_validation->set_error_delimiters('', ''); - // TODO check if user is logged in - if ($this->form_validation->run('upload') === FALSE) { $params = array('title' => @@ -140,18 +141,37 @@ class Video extends CI_Controller { { $this->load->model('videos_model'); $this->load->helper('video'); + $this->config->load('content_ingestion'); - $file_name = './data/upload/'. $_FILES['video-upload-file']['name']; + $file_name = $this->uploaded_file; $av_info = get_av_info($file_name); + $name = urlencode(str_replace(' ', '-', + $this->input->post('video-title'))); + $category_id = $this->input->post('video-category'); + + // Prepare formats + $formats = $this->config->item('formats'); + $prepared_formats = prepare_formats($formats, $av_info, + $this->config->item('elim_dupl_res')); - // TODO category_id, user_id -// $this->videos_model->add_video( -// $this->input->post('video-title'), -// $this->input->post('video-description'), -// $this->input->post('video-tags'), -// $av_info, 0, 1); + // Add video to DB. + $activation_code = $this->videos_model->add_video($name, + $this->input->post('video-title'), + $this->input->post('video-description'), + $this->input->post('video-tags'), + $av_info['duration'], + $prepared_formats['db_formats'], $category_id, $user_id); - // TODO call CIS + // Send a content ingestion request to + // CIS (Content Ingestion Server). + $this->_send_content_ingestion($activation_code, + $file_name, + $name, $av_info['size'], + $prepared_formats['transcode_configs']); + + $this->load->helper('message'); + show_info_msg_page($this, + $this->lang->line('video_msg_video_uploaded')); } } @@ -251,6 +271,50 @@ class Video extends CI_Controller { return $output; } + /** + * Request content_ingest to the CIS in order to start the content + * ingestion process. + * + * @param string $activation_code + * @param string $raw_video_fn uploaded video file name + * @param string $name + * @param int $raw_video_size uploaded video file size in bytes + * @param array $transcode_configs dictionary which must be included in + * the JSON data that needs to be sent to CIS + * @return mixed return the HTTP content (body) on success and FALSE + * otherwise + */ + protected function _send_content_ingestion($activation_code, $raw_video_fn, + $name, $raw_video_size, $transcode_configs) + { + $this->config->load('content_ingestion'); + + $url = $this->config->item('cis_url') . 'ingest_content'; + $data = array( + 'code'=>$activation_code, + 'raw_video'=>$raw_video_fn, + 'name'=>$name, + 'weight'=>$raw_video_size, + 'transcode_configs'=>$transcode_configs, + 'thumbs'=>$this->config->item('thumbs_count') + ); + $json_data = json_encode($data); + + // Send request to CIS. + $r = new HttpRequest($url, HttpRequest::METH_POST); + $r->setBody($json_data); + try + { + $response = $r->send()->getBody(); + } + catch (HttpException $ex) + { + return FALSE; + } + + return $response; + } + public function _is_user_loggedin($param) { if (! $this->session->userdata('user_id')) @@ -297,6 +361,8 @@ class Video extends CI_Controller { if ($this->upload->do_upload('video-upload-file')) { + $this->uploaded_file = $this->upload->data(); + $this->uploaded_file = $this->uploaded_file['file_name']; return TRUE; } else diff --git a/application/helpers/video_helper.php b/application/helpers/video_helper.php index b845898..67ede1a 100644 --- a/application/helpers/video_helper.php +++ b/application/helpers/video_helper.php @@ -117,8 +117,77 @@ function get_av_info($file_name) { // TODO use ffprobe to return width, height, DAR, duration and size of a video - return array('width'=> 800, 'height'=> 600, 'dar'=> '16:9', - 'duration'=> '00:10', 'size'=> 1101693); + return array('width'=> 1440, 'height'=> 1080, 'dar'=> '16:9', + 'duration'=> '00:10', 'size'=> 5568748); +} + +/** + * Return a dictionary with formats compliant for DB and CIS and computes + * resolutions such that an uploaded video will not be converted to a higher + * resolution. + * + * @param type $formats formats as in content_ingestion config file + * @param type $av_info structure as returned by get_av_info function from this + * helper + * @param type $elim_dupl_res eliminate consecutive formats with the same + * resolution + * @return array a dictionary with DB format at key 'db_formats' and CIS format + * at key 'transcode_configs' + */ +function prepare_formats($formats, $av_info, $elim_dupl_res=FALSE) +{ + $transcode_configs = array(); + $db_formats = array(); + + for ($i = 0; $i < count($formats); $i++) + { + $transcode_configs[$i]['container'] = $formats[$i]['container']; + $transcode_configs[$i]['extension'] = $formats[$i]['extension']; + $db_formats[$i]['ext'] = $formats[$i]['extension']; + $transcode_configs[$i]['a_codec'] = $formats[$i]['audio_codec']; + $transcode_configs[$i]['a_bitrate'] = $formats[$i]['audio_bit_rate']; + $transcode_configs[$i]['a_samplingrate'] = $formats[$i]['audio_sampling_rate']; + $transcode_configs[$i]['a_channels'] = $formats[$i]['audio_channels']; + $transcode_configs[$i]['v_codec'] = $formats[$i]['video_codec']; + $transcode_configs[$i]['v_bitrate'] = $formats[$i]['video_bit_rate']; + $transcode_configs[$i]['v_framerate'] = $formats[$i]['video_frame_rate']; + $transcode_configs[$i]['v_dar'] = $av_info['dar']; + $db_formats[$i]['dar'] = $av_info['dar']; + + $sar = $av_info['width'] / $av_info['height']; + + if ($av_info['height'] < $formats[$i]['video_height']) + { + $width = $av_info['width']; + $height = $av_info['height']; + } + else + { + $height = $formats[$i]['video_height']; + $width = round($sar * $height); + } + + $transcode_configs[$i]['v_resolution'] = "${width}x${height}"; + $db_formats[$i]['res'] = "${width}x${height}"; + } + + // Eliminate formats with duplicate resolutions. + if ($elim_dupl_res) + { + for ($i = 1; $i < count($transcode_configs); $i++) + { + if ($transcode_configs[$i]['v_resolution'] + === $transcode_configs[$i - 1]['v_resolution']) + { + unset($transcode_configs[$i - 1]); + unset($db_formats[$i - 1]); + $i--; + } + } + } + + return array('transcode_configs'=>$transcode_configs, + 'db_formats'=>$db_formats); } /* End of file video_helper.php */ diff --git a/application/language/english/video_lang.php b/application/language/english/video_lang.php index 459a5df..92b93df 100644 --- a/application/language/english/video_lang.php +++ b/application/language/english/video_lang.php @@ -19,6 +19,7 @@ $lang['video_submit_post_comment'] = 'Post'; $lang['video_upload_file'] = 'Video File'; $lang['video_title'] = 'Title'; $lang['video_description'] = 'Description'; +$lang['video_category'] = 'Category'; $lang['video_tags'] = 'Tags'; $lang['video_tags_hint'] = 'comma separated tags'; $lang['video_submit_upload'] = 'Upload'; diff --git a/application/models/videos_model.php b/application/models/videos_model.php index b03cd16..f927561 100644 --- a/application/models/videos_model.php +++ b/application/models/videos_model.php @@ -248,28 +248,23 @@ class Videos_model extends CI_Model { return $video; } - public function compute_video_name($title) - { - $name = str_replace(' ', '-', $title); - - return urlencode($name); - } - /** * Adds a new uploaded video to the DB. * - * @param type $title - * @param type $description - * @param type $tags comma separated tags - * @param type $av_info a dictionary of video properties containing keys - * width, height, dar (display aspect ratio), duration and size; is can be - * returned with function get_av_info from video helper + * @param string $name + * @param string $title + * @param string $description + * @param string $tags comma separated tags + * @param string $duration video duration formatted [HH:]mm:ss + * @param array $formats a dictionary corresponding to `formats` JSON + * column from `videos` table + * @param int $category_id + * @param int $user_id + * @return mixed returns an activation code on success or FALSE otherwise */ - public function add_video($title, $description, $tags, $av_info, - $category_id, $user_id) + public function add_video($name, $title, $description, $tags, $duration, + $formats, $category_id, $user_id) { - $name = $this->compute_video_name($title); - // Tags. $json_tags = array(); $tok = strtok($tags, ','); @@ -282,15 +277,13 @@ class Videos_model extends CI_Model { $json_tags = json_encode($json_tags); // TODO formats - $json_formats = '[{"res":"1280x720","ext":"ogv","dar":"16:9"},' - . '{"res":"1067x600","ext":"ogv","dar":"16:9"}]'; - + $json_formats = json_encode($formats); $query = $this->db->query("INSERT INTO `videos` (name, title, description, duration, formats, category_id, user_id, tags, date) - VALUES ('$name', '$title', '$description', '" - . $av_info['duration']. "', '$json_formats', $category_id, + VALUES ('$name', '$title', '$description', '$duration', + '$json_formats', $category_id, $user_id, '$json_tags', utc_timestamp())"); if ($query === FALSE) return FALSE; @@ -308,6 +301,8 @@ class Videos_model extends CI_Model { $query = $this->db->query("INSERT INTO `videos_unactivated` (video_id, activation_code) VALUES ($video_id, '$activation_code')"); + + return $activation_code; } /** diff --git a/application/views/header.php b/application/views/header.php index 475239f..c1867c2 100644 --- a/application/views/header.php +++ b/application/views/header.php @@ -87,7 +87,7 @@ 'quick-search')); ?> : + $search_category_name, 'id="search-category"') ?>: