동영상을 미리보기 및 재생하는 웹 앱

개요



동영상을 나열하고 미리보기를 클릭하여 재생할 수있는 웹 앱

종속 환경



Flask 1.0+
Bootstarp 4
파이썬 3.4+
pymongo,joblib
MongoDB 3.6+(on Docker)
ffmpeg
(Imagemagic-6)
Linux Mint 19.1에서 동작 확인

사용법



GitHub에서 프로그램을 공개하고 있다. ( htps : // 기주 b. 코 m/미마부라오/모ゔぃ에 b로 w세 r. 기 t )
- 동영상 재생
- 데이터베이스 새로 만들기
- 정렬 순서 변경
- 데이터베이스 업데이트

동작



Flask는 @app.route에 의해 받은 url에 따라 함수를 반환하는 구조로 되어 있다. 그리고 return render_template에서 지정한 html을 호출한다.
제 경우에는 대략적으로 그림 1과 같은 구성으로 했다.

-/movie

moviebrowser.py

@app.route('/movie', methods=['GET','POST'])
def show_all(data_all=[]):
    global my_database
    my_database.index_howto = request.args.get('index_sort',default='views', type=str)
    my_database.search_id = ''
    my_database.search = ''

    if(request.method == 'GET'): #検索窓の取得(何故かGETメソッド)
        my_database.search = request.args.get('search', default='', type=str)
        skip = request.args.get('page', default='', type=str)  #データベースのスキップ
    data_all.clear()
    if( my_database.thumnail_images == {} ):
        data_all = my_database.read_db_thumnail(data_all,skip)
    else:
        data_all = my_database.read_db_thumnail(data_all,skip)

    return render_template('show.html', data_all=data_all)


Mongo의 데이터베이스에 등록된 데이터를 data_all의 리스트에 읽어 show.html에 흘리는 느낌이다.

show.html
{% extends "layout.html" %}
{% block title %}Movie Database{% endblock %}

{% block content %}
<nav class="navbar navbar-fixed-top sticky-top navbar-dark bg-dark">
    <a href="/movie" class="navbar-brand">MovieBrowser</a>
    <form class="form-inline my-2 my-lg-0">
      <input type="search"  name = "search" class="form-control mr-sm-2" placeholder="検索..." aria-label="検索...">
      <button type="submit" class="btn btn-outline-success my-2 my-sm-0">検索</button>
    </form>
    <button class="navbar-toggler" type="button"
        data-toggle="collapse"
        data-target="#navmenu1"
        aria-controls="navmenu1"
        aria-expanded="false"
        aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navmenu1">
      <div class="navbar-nav">
        <a class="nav-item nav-link" href="/select_database">データーベース変更</a>
        <a class="nav-item nav-link" href="#">#</a>
        <a class="nav-item nav-link" href="#">#</a>
        <a class="nav-item nav-link" href="/manager">管理</a>
        <a class="nav-item nav-link" href="/update">更新</a>
      </div>
    </div>
  </nav>

<div class="table-responsive">
    <table class="table table-dark table-striped">
      <thread>
        <tr>
          <th></th>
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=views" role="button">views</a></th>
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=star" role="button"></a></th>          
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=date" role="button">日付</a></th>
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=duration" role="button">時間</a></th>
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=access_time" role="button">アクセス日付</a></th>
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=filename" role="button">ファイル名</a></th>
          <th><a type="button" class="btn btn-dark" href="/movie?index_sort=size" role="button">ファイルサイズ(MByte)</a></th>          
        </tr>
      </thread>
      <tbody>
        {% for samp in data_all %}
        <tr>
            <td><a href="/play?id_number={{ samp["_id"] }}""> <img src={{ samp["thumnail_file"] }} alt="test"> </a></td>
            <td>{{ samp["views"] }}回</td>
          <td>
            <a href="/star?stars=0&id_number={{ samp["_id"] }}" class="badge badge-dark" data-toggle="tooltip" data-placement="top" title="星を無くしますか">★{{ samp["star"] }}</a>
            <a href="/star?stars=1&id_number={{ samp["_id"] }}" class="badge badge-dark"></a>
            <a href="/star?stars=2&id_number={{ samp["_id"] }}" class="badge badge-dark">★★</a>
            <a href="/star?stars=3&id_number={{ samp["_id"] }}" class="badge badge-dark">★★★</a></td>

          <td>{{ samp["date"] }}</td>
          <td>{{ samp["duration"] }}</td>
          <td>{{ samp["access_time"] }}</td>
          <td>{{ samp["name"] }}</td>
          <td>{{ samp["size"] }}</td>
        </tr>
        {% else %}
          <td>no entry exist!</td>
        {% endfor %}
      </tbody>
    </table>
    <a type="button" class="btn btn-dark btn-block" href="/movie?page=pre" role="button"></a>
  <a type="button" class="btn btn-dark btn-block" href="/movie?page=next" role="button"></a>
  </div>
</div>

{% endblock %}

{{}}이 되고 있는 부분은 render_template로 지정한 변수를 넣을 수 있다. 여기서, 동화상의 각 정보 (파일명, 섬네일 화상 등)를 테이블로서 표시 할 수있다. 이 변수를 받을 수 있는 구조는 jinja2라고 하는 것 같다. 또 제어 구문을 html내에서 이용할 수 있도록 하고 있다.
html의 각 부품은 Bootstrap에서 제공되며, 주로 버튼, 테이블, 배지 등을 이용하고 있다.

감상



최초의 웹 앱의 작성이었다. 실용적인 것을 만들고 싶다고 모여 있던 동영상을 내용이 3컷 정도로 볼 수 있는 앱을 원했다.
github에 등록하여 Microsoft Visual CODE를 이용해 보았지만 편리했다. 그리고, 만든 자작의 클래스나 함수도 팝업 형식으로 인수등을 가르쳐 주고 잇달아 만드는 일이다.
Flask도 당연히 처음이지만, 웹 앱으로서 메이저인 Django는 사용한 적이 없었다. 모처럼이므로 심플한 프레임워크로 했다.
데이터베이스를 이용한 프로그램에도 도전하고 싶어서 NoSQL 계열의 mongo가 재미있게 뛰어들었다. 될 수 있으면 재미있었습니다.
그 중에서도 github에서 readme.md에는 힘을 쏟았다. 프로그램에 기능을 추가해서는 추기해 가는 스타일이 되었다. 프로그램이란 이런 과정에서 완성된 갈 것이다.
이용 면에서는 당초 생각했던 기능은 생겨서 이번에 공개해 보았다.
그렇다고 해도 동영상 재생 어플의 mpv는 쇼트 컷 동작의 상, 심플하고 매우 편리하다.

참조



Bootstrap 공식( htps : // 게이 t보오 tst et al p. 코m/ )
Mongo 공식( htps //w w. 몽고 db. 이 m/jp )
Flask 공식( htp://f sk. 포코오. rg/ )

좋은 웹페이지 즐겨찾기