본문 바로가기

회고록(TIL&WIL)

TIL 2022.05.19 머신러닝 팀프로젝트(object detection) - 2 (video 태그, 동영상 업로드(미리보기), glob, os.path)

video 태그

<video autoplay controls loop muted poster="thumnail.jpg" preload="auto">
<source src="/static/video/abc.mp4" type="video/mp4">
zzz
</video>
  • autoplay : 동영상을 자동으로 재생한다.
  • controls : 재생, 정지 등 조작 메뉴를 보여준다.
  • loop : 동영상을 반복 재생한다.
  • poster : 동영상 재생 전에 보여줄 이미지이다.
  • preload : 페이지를 열 때 무엇을 로드할지 정한다.
    • auto : 동영상, 메타데이타 모두 로드한다.
    • metadata : 메타데이타만 로드한다.
    • none : 로드하지 않는다.
  • source
    • src : 동영상 위치를 입력한다. 웹브라우저가 가장 많이 지원하는 형식은 MP4이다.
    • type : 동영상 타입을 알려준다. 만약 MP4 파일이라면 video/mp4라고 적는다.
  • zzz : 웹브라우저가 video 태그를 지원하지 않을 때 출력될 텍스트이다.

상충되거나 혼자서는 작동하지 않는 속성이 있다. 예를 들어 autoplay로 정하면 preload는 무시된다. 크롬 등 일부 웹브라우저에서는 muted와 autoplay를 같이 사용해야 자동 시작이 작동한다.

 

동영상 업로드, 미리보기 구현

main.py

<h1> 파일로 동영상 업로드 하기 </h1>
<div id="video_file_div">
    <input id="video_file" type="file">
    <button class='btn' onclick="video_uplaod()">업로드</button>
</div>
<div id="video_preview">
</div>
function video_uplaod() {
    let file = $('#video_file')[0].files[0]
    let form_data = new FormData()
    form_data.append("video", file)
    $.ajax({
        type: "POST",
        url: "/main/api/video/upload",
        data: form_data,
        contentType: false,
        processData: false,
        success: function (response){
            alert(response['result'])
            let video_src = response['video']
            let temp_html = `<video id="video_preview" autoplay controls muted preload="auto" width="300px" height="300px">
                                <source src="${video_src}" type="video/mp4">
                                지원되지 않는 브라우저 입니다.
                            </video>`
            $('#video_preview').html(temp_html)
        }

})

동영상도 이미지와 똑같이 file 형식으로 백엔드로 보내야하는 것은 동일하며 저장한 결과값을 response로 받아와서 temp_html에 video태그를 저장해서 쏴주는 식으로 미리보기를 구현해보았다. video 태그를 미리 만들어 두고 src를 변경하는 것은 되지않았어서 html 함수로 쏴주는 식으로 구현을 했고 백틱`` 안에서 변수를 사용하기 위해서 ${변수명}의 형태로 하니 사용 할 수 있었다.

@bp.route("/api/video/upload", methods=['POST'])
def video_upload():
    print('video_upload()실행')
    file = request.files['video']  # werkzeug.datastructures.FileStorage, name
    print(file) # 파일스토리지해서 파일의 내용 불러옴
    extension = secure_filename(file.filename).split('.')[-1]
    print(extension) # 확장자만 추출
    f_name = file.filename.replace('.' + extension, '') 
    print(f_name) # 파일명만 추출

    # 파일 이름 , Local에 Upload 한 이미지 저장
    today = datetime.now()
    today = today.strftime('%Y-%m-%d-%H-%M-%S')
    filename = f_name + '-' + today  # test1-2022-05-19-14-43-23.jpg
    upload_path = 'static/upload_data/' + filename + '.' + extension'
    print('upload_path: ', upload_path) # 최종 파일 경로
    file.save(upload_path)  # 'static/upload_data/test1.jpg

    # DB에 Image Path 저장
    doc = {
        'id': 'id',
        'company': 'samsung',
        'isPass': True,
        'helmet': 0,
        'head': 0,
        'score': 0.0,
        'date': today,
        'upload_path': upload_path
    }
    db.result.insert_one(doc)
    return jsonify({'result': 'success', 'video': upload_path})

glob 모듈

glob()

파일 리스트를 뽑아올 때 사용한다.

* : 임의의 글자 0개 이상

? : 임의의 한 글자

[] : 특정 문자 한글자(예를 들어 [0-9]는 0부터 9사이의 숫자를 의미하며, [a-z]는 알파벳 a부터 z까지를 의미합니다.)

파이썬 3.5부터 ** 와일드카드 2개를 사용해 재귀 처리를 할 수 있게 되었습니다.

파라미터 recursive=True 로 설정하고 ** 로 작성하면 하위 폴더에도 접근할 수 있습니다.

from glob import glob #임포트 해와서

glob('*.exe') # exe 파일 다 뽑아옴
['python.exe', 'pythonw.exe']

glob('*.txt') # txt 파일 다 뽑아옴
['LICENSE.txt', 'NEWS.txt']

glob() 함수는 인자로 받은 패턴과 이름이 일치하는 모든 파일과 디렉터리의 리스트를 반환합니다. 패턴을 그냥 *라고 주면 모든 파일과 디렉터리를 볼 수 있다.

os.path 모듈

  • 코드 내에서 직접 파일을 다루는 경우 os.path 모듈을 사용하게 된다.
  • os.path 내에는 경로반환, 경로추출 등 파일/디렉토리 경로와 관련된 많은 함수를 제공해준다.

abspath(path)

path의 절대경로를 반환한다. 입력받은 path에는 파일 혹은 폴더 이름이 들어온다.

import os.path
os.path.abspath("temp")
'/Users/Desktop/temp'

basename(path)

path의 기본이름을 반환한다. 입력받은 path에는 절대경로가 들어온다. (abspath와 반대되는 함수)

import os.path
os.path.basename('/Users/Desktop/temp/test.txt')
'test.txt'

dirname(path)

path의 파일/디렉토리 경로를 반환한다.

import os.path
os.path.dirname('/Users/Desktop/temp/test.txt')
'/Users/Desktop/temp'

exists(path)

입력받은 path가 존재하면 True, 존재하지 않으면 False를 반환한다,

import os.path
os.path.exists('/Users/Desktop/temp/test.txt')
True
  • 코드내에 파일저장의 명령이 있을경우, 이를 반복실행하게 되면 파일 저장명령 역시 반복하게 된다. 이를 방지하기 위해 많이 사용한다.

getmtime(path)

path에 대한 최근 변경시간을 반환한다. 파일이 없는 경우에는 error를 발생시킨다.

import os.path
import time

time.gmtime(getmtime('/Users/Desktop/temp/test.txt'))
  • getctime(path) : 생성시간 반환
  • getatime(path) : 최근접근시간 반환

getsize(path)

path의 파일크기를 바이트단위로 반환한다.

import os.path
os.path.getsize('/Users/Desktop/temp/test.txt')

isdir(path)

path가 디렉토리이면 True, 아니면 False를 반환한다.

import os.path
os.path.isdir('/Users/Desktop/temp/test.txt')
False
  • isfile(path) : 파일인지 확인
  • isabs(path) : 절대경로인지 확인

join(path1, path2, …)

OS의 형식에 맞게 각각의 경로들을 하나의 경로로 이어준다.

import os.path
os.path.join("/Users/Desktop","Temp","test.txt")
'/Users/Desktop/Temp/test.txt'

normpath(path)

path에서 . / .. 과 같은 구분자를 제거해 path를 정규화시킨다. (=원래 path의 패턴으로 만들어 준다)

import os.path
os.path.normpath('/Users//Desktop/../temp/./test.txt')
'/Users/Desktop/temp/text.txt'
  • normcase(path) : path의 문자열을 정규화한다. (소문자로 바꾸고 / 형식에 맞게)

split(path)

path를 디렉토리와 파일로 분리한다.

import os.path
os.path.split('/Users/Desktop/temp/test.txt')
'/Users/Desktop/temp','test.txt'

os.path 모듈을 이용해서 경로값을 저장하고 그 경로값을 원하는 형식대로 glob을 이용해서 가져올 수 있다. 둘이 함께쓰는 경우가 많다.