Ejemplo n.º 1
0
    def check_media(self, n_player, file_path, flag_path):
        """
        check media and add them to list view if duration > 0

        Args:
            n_player (str): player to add media
            file_path (str): media file path to be checked
            flag_path (bool): True include full path of media else only basename

        Returns:
             bool: True if file is media else False
        """

        #nframes, videoDuration_ms, videoDuration_s, fps, hasVideo, hasAudio = accurate_media_analysis(self.ffmpeg_bin, file_path)
        r = utilities.accurate_media_analysis(self.ffmpeg_bin, file_path)
        if "error" in r:
            return False
        else:
            if r["duration"] > 0:
                if not flag_path:
                    file_path = str(Path(file_path).name)
                self.mediaDurations[file_path] = float(r["duration"])
                self.mediaFPS[file_path] = float(r["fps"])
                self.mediaHasVideo[file_path] = r["has_video"]
                self.mediaHasAudio[file_path] = r["has_audio"]
                self.add_media_to_listview(n_player, file_path)
                return True
            else:
                return False
Ejemplo n.º 2
0
 def test_media_ok(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/geese1.mp4")
     assert r == {
         'frames_number': 1548,
         'duration_ms': Decimal('61920.00'),
         'duration': Decimal('61.92'),
         'fps': Decimal('25'),
         'has_video': True,
         'has_audio': True,
         'bitrate': 901,
         'resolution': '640x480'
     }
Ejemplo n.º 3
0
def open_project_json(projectFileName):
    """
    open project json

    Args:
        projectFileName (str): path of project

    Returns:
        str: project path
        bool: True if project changed
        dict: BORIS project
        str: message
    """

    logging.debug("open project: {0}".format(projectFileName))

    projectChanged = False
    msg = ""

    if not os.path.isfile(projectFileName):
        return projectFileName, projectChanged, {
            "error": "File {} not found".format(projectFileName)
        }, msg

    try:
        s = open(projectFileName, "r").read()
    except PermissionError:
        return projectFileName, projectChanged, {
            "error": "File {}: Permission denied".format(projectFileName)
        }, msg
    except Exception:
        return projectFileName, projectChanged, {
            "error":
            "Error on file {}: {}".format(projectFileName,
                                          sys.exc_info()[1])
        }, msg

    try:
        pj = json.loads(s)
    except json.decoder.JSONDecodeError:
        return projectFileName, projectChanged, {
            "error": "This project file seems corrupted"
        }, msg
    except Exception:
        return projectFileName, projectChanged, {
            "error":
            "This project file seems corruptedError on file {}: {}".format(
                projectFileName,
                sys.exc_info()[1])
        }, msg

    # transform time to decimal
    pj = utilities.convert_time_to_decimal(pj)

    # add coding_map key to old project files
    if "coding_map" not in pj:
        pj["coding_map"] = {}
        projectChanged = True

    # add subject description
    if "project_format_version" in pj:
        for idx in [x for x in pj[SUBJECTS]]:
            if "description" not in pj[SUBJECTS][idx]:
                pj[SUBJECTS][idx]["description"] = ""
                projectChanged = True

    # check if project file version is newer than current BORIS project file version
    if "project_format_version" in pj and Decimal(
            pj["project_format_version"]) > Decimal(project_format_version):
        return (
            projectFileName,
            projectChanged,
            {
                "error":
                ("This project file was created with a more recent version of BORIS.<br>"
                 "You must update BORIS to <b>v. >= {}</b> to open this project"
                 ).format(pj["project_format_version"])
            },
            msg,
        )

    # check if old version  v. 0 *.obs
    if "project_format_version" not in pj:

        # convert VIDEO, AUDIO -> MEDIA
        pj["project_format_version"] = project_format_version
        projectChanged = True

        for obs in [x for x in pj[OBSERVATIONS]]:

            # remove 'replace audio' key
            if "replace audio" in pj[OBSERVATIONS][obs]:
                del pj[OBSERVATIONS][obs]["replace audio"]

            if pj[OBSERVATIONS][obs][TYPE] in ["VIDEO", "AUDIO"]:
                pj[OBSERVATIONS][obs][TYPE] = MEDIA

            # convert old media list in new one
            if len(pj[OBSERVATIONS][obs][FILE]):
                d1 = {PLAYER1: [pj[OBSERVATIONS][obs][FILE][0]]}

            if len(pj[OBSERVATIONS][obs][FILE]) == 2:
                d1[PLAYER2] = [pj[OBSERVATIONS][obs][FILE][1]]

            pj[OBSERVATIONS][obs][FILE] = d1

        # convert VIDEO, AUDIO -> MEDIA
        for idx in [x for x in pj[SUBJECTS]]:
            key, name = pj[SUBJECTS][idx]
            pj[SUBJECTS][idx] = {"key": key, "name": name, "description": ""}

        msg = (
            "The project file was converted to the new format (v. {}) in use with your version of BORIS.<br>"
            "Choose a new file name for saving it."
        ).format(project_format_version)
        projectFileName = ""

    # update modifiers to JSON format

    # check if project format version < 4 (modifiers were str)
    project_lowerthan4 = False
    if "project_format_version" in pj and utilities.versiontuple(
            pj["project_format_version"]) < utilities.versiontuple("4.0"):
        for idx in pj[ETHOGRAM]:
            if pj[ETHOGRAM][idx]["modifiers"]:
                if isinstance(pj[ETHOGRAM][idx]["modifiers"], str):
                    project_lowerthan4 = True
                    modif_set_list = pj[ETHOGRAM][idx]["modifiers"].split("|")
                    modif_set_dict = {}
                    for modif_set in modif_set_list:
                        modif_set_dict[str(len(modif_set_dict))] = {
                            "name": "",
                            "type": SINGLE_SELECTION,
                            "values": modif_set.split(",")
                        }
                    pj[ETHOGRAM][idx]["modifiers"] = dict(modif_set_dict)
            else:
                pj[ETHOGRAM][idx]["modifiers"] = {}

        if not project_lowerthan4:
            msg = "The project version was updated from {} to {}".format(
                pj["project_format_version"], project_format_version)
            pj["project_format_version"] = project_format_version
            projectChanged = True

    # add category key if not found
    for idx in pj[ETHOGRAM]:
        if "category" not in pj[ETHOGRAM][idx]:
            pj[ETHOGRAM][idx]["category"] = ""

    # if one file is present in player #1 -> set "media_info" key with value of media_file_info
    for obs in pj[OBSERVATIONS]:
        if pj[OBSERVATIONS][obs][TYPE] in [
                MEDIA
        ] and MEDIA_INFO not in pj[OBSERVATIONS][obs]:
            pj[OBSERVATIONS][obs][MEDIA_INFO] = {
                LENGTH: {},
                "fps": {},
                "hasVideo": {},
                "hasAudio": {}
            }
            for player in [PLAYER1, PLAYER2]:
                # fix bug Anne Maijer 2017-07-17
                if pj[OBSERVATIONS][obs][FILE] == []:
                    pj[OBSERVATIONS][obs][FILE] = {"1": [], "2": []}

                for media_file_path in pj[OBSERVATIONS][obs]["file"][player]:
                    # FIX: ffmpeg path
                    ret, msg = utilities.check_ffmpeg_path()
                    if not ret:
                        return projectFileName, projectChanged, {
                            "error": "FFmpeg path not found"
                        }, ""
                    else:
                        ffmpeg_bin = msg

                    r = utilities.accurate_media_analysis(
                        ffmpeg_bin, media_file_path)

                    if "duration" in r and r["duration"]:
                        pj[OBSERVATIONS][obs][MEDIA_INFO][LENGTH][
                            media_file_path] = float(r["duration"])
                        pj[OBSERVATIONS][obs][MEDIA_INFO][FPS][
                            media_file_path] = float(r["fps"])
                        pj[OBSERVATIONS][obs][MEDIA_INFO]["hasVideo"][
                            media_file_path] = r["has_video"]
                        pj[OBSERVATIONS][obs][MEDIA_INFO]["hasAudio"][
                            media_file_path] = r["has_audio"]
                        project_updated, projectChanged = True, True
                    else:  # file path not found
                        if ("media_file_info" in pj[OBSERVATIONS][obs] and len(
                                pj[OBSERVATIONS][obs]["media_file_info"]) == 1
                                and len(
                                    pj[OBSERVATIONS][obs][FILE][PLAYER1]) == 1
                                and len(pj[OBSERVATIONS][obs][FILE][PLAYER2])
                                == 0):
                            media_md5_key = list(pj[OBSERVATIONS][obs]
                                                 ["media_file_info"].keys())[0]
                            # duration
                            pj[OBSERVATIONS][obs][MEDIA_INFO] = {
                                LENGTH: {
                                    media_file_path:
                                    pj[OBSERVATIONS][obs]["media_file_info"]
                                    [media_md5_key]["video_length"] / 1000
                                }
                            }
                            projectChanged = True

                            # FPS
                            if "nframe" in pj[OBSERVATIONS][obs][
                                    "media_file_info"][media_md5_key]:
                                pj[OBSERVATIONS][obs][MEDIA_INFO][FPS] = {
                                    media_file_path:
                                    pj[OBSERVATIONS][obs]["media_file_info"]
                                    [media_md5_key]["nframe"] /
                                    (pj[OBSERVATIONS][obs]["media_file_info"]
                                     [media_md5_key]["video_length"] / 1000)
                                }
                            else:
                                pj[OBSERVATIONS][obs][MEDIA_INFO][FPS] = {
                                    media_file_path: 0
                                }

    # update project to v.7 for time offset second player
    project_lowerthan7 = False
    for obs in pj[OBSERVATIONS]:
        if "time offset second player" in pj[OBSERVATIONS][obs]:
            if MEDIA_INFO not in pj[OBSERVATIONS][obs]:
                pj[OBSERVATIONS][obs][MEDIA_INFO] = {}
            if "offset" not in pj[OBSERVATIONS][obs][MEDIA_INFO]:
                pj[OBSERVATIONS][obs][MEDIA_INFO]["offset"] = {}
            for player in pj[OBSERVATIONS][obs][FILE]:
                pj[OBSERVATIONS][obs][MEDIA_INFO]["offset"][player] = 0.0
            if pj[OBSERVATIONS][obs]["time offset second player"]:
                pj[OBSERVATIONS][obs][MEDIA_INFO]["offset"]["2"] = float(
                    pj[OBSERVATIONS][obs]["time offset second player"])

            del pj[OBSERVATIONS][obs]["time offset second player"]
            project_lowerthan7 = True

            msg = (
                "The project file was converted to the new format (v. {project_version}) in use with your version of BORIS.<br>"
                "Please note that this new version will NOT be compatible with previous BORIS versions (&lt; v. {project_version}).<br>"
            ).format(project_version=project_format_version)

            projectChanged = True

    if project_lowerthan7:

        msg = (
            "The project was updated to the current project version ({project_format_version})."
        ).format(project_format_version=project_format_version)

        try:
            copyfile(
                projectFileName,
                projectFileName.replace(
                    ".boris",
                    ".v{}.boris".format(pj["project_format_version"])))
            msg += "\n\nThe old file project was saved as {}".format(
                projectFileName.replace(
                    ".boris",
                    ".v{}.boris".format(pj["project_format_version"])))
        except Exception:
            pass

        pj["project_format_version"] = project_format_version

    return projectFileName, projectChanged, pj, msg
Ejemplo n.º 4
0
def open_project_json(projectFileName):
    """
    open project json
    
    Args:
        projectFileName (str): path of project
        
    Returns:
        str: project path
        bool: True if project changed
        dict: BORIS project
        str: message
    """

    logging.debug("open project: {0}".format(projectFileName))

    projectChanged = False
    msg = ""

    if not os.path.isfile(projectFileName):
        return projectFileName, projectChanged, {
            "error": "File {} not found".format(projectFileName)
        }, msg

    s = open(projectFileName, "r").read()

    try:
        pj = json.loads(s)
    except:
        return projectFileName, projectChanged, {
            "error": "This project file seems corrupted"
        }, msg

    # transform time to decimal
    pj = utilities.convert_time_to_decimal(pj)

    # add coding_map key to old project files
    if not "coding_map" in pj:
        pj["coding_map"] = {}
        projectChanged = True

    # add subject description
    if "project_format_version" in pj:
        for idx in [x for x in pj[SUBJECTS]]:
            if not "description" in pj[SUBJECTS][idx]:
                pj[SUBJECTS][idx]["description"] = ""
                projectChanged = True

    # check if project file version is newer than current BORIS project file version
    if "project_format_version" in pj and Decimal(
            pj["project_format_version"]) > Decimal(project_format_version):

        return projectFileName, projectChanged, {
            "error":
            ("This project file was created with a more recent version of BORIS.\n"
             "You must update BORIS to open it")
        }, msg

    # check if old version  v. 0 *.obs
    if "project_format_version" not in pj:

        # convert VIDEO, AUDIO -> MEDIA
        pj['project_format_version'] = project_format_version
        projectChanged = True

        for obs in [x for x in pj[OBSERVATIONS]]:

            # remove 'replace audio' key
            if "replace audio" in pj[OBSERVATIONS][obs]:
                del pj[OBSERVATIONS][obs]['replace audio']

            if pj[OBSERVATIONS][obs][TYPE] in ['VIDEO', 'AUDIO']:
                pj[OBSERVATIONS][obs][TYPE] = MEDIA

            # convert old media list in new one
            if len(pj[OBSERVATIONS][obs][FILE]):
                d1 = {PLAYER1: [pj[OBSERVATIONS][obs][FILE][0]]}

            if len(pj[OBSERVATIONS][obs][FILE]) == 2:
                d1[PLAYER2] = [pj[OBSERVATIONS][obs][FILE][1]]

            pj[OBSERVATIONS][obs][FILE] = d1

        # convert VIDEO, AUDIO -> MEDIA
        for idx in [x for x in pj[SUBJECTS]]:
            key, name = pj[SUBJECTS][idx]
            pj[SUBJECTS][idx] = {"key": key, "name": name, "description": ""}

        msg = (
            "The project file was converted to the new format (v. {}) in use with your version of BORIS.<br>"
            "Choose a new file name for saving it."
        ).format(project_format_version)
        projectFileName = ""

    for obs in pj[OBSERVATIONS]:
        if not "time offset second player" in pj[OBSERVATIONS][obs]:
            pj[OBSERVATIONS][obs]["time offset second player"] = Decimal("0.0")
            projectChanged = True

    # update modifiers to JSON format

    project_lowerthan4 = False

    logging.debug("project_format_version: {}".format(
        utilities.versiontuple(pj["project_format_version"])))

    if "project_format_version" in pj and utilities.versiontuple(
            pj["project_format_version"]) < utilities.versiontuple("4.0"):

        for idx in pj[ETHOGRAM]:
            if pj[ETHOGRAM][idx]["modifiers"]:
                if isinstance(pj[ETHOGRAM][idx]["modifiers"], str):
                    project_lowerthan4 = True
                    modif_set_list = pj[ETHOGRAM][idx]["modifiers"].split("|")
                    modif_set_dict = {}
                    for modif_set in modif_set_list:
                        modif_set_dict[str(len(modif_set_dict))] = {
                            "name": "",
                            "type": SINGLE_SELECTION,
                            "values": modif_set.split(",")
                        }
                    pj[ETHOGRAM][idx]["modifiers"] = dict(modif_set_dict)
            else:
                pj[ETHOGRAM][idx]["modifiers"] = {}

        if not project_lowerthan4:
            msg = "The project version was updated from {} to {}".format(
                pj["project_format_version"], project_format_version)
            pj["project_format_version"] = project_format_version
            projectChanged = True

    # add category key if not found
    for idx in pj[ETHOGRAM]:
        if "category" not in pj[ETHOGRAM][idx]:
            pj[ETHOGRAM][idx]["category"] = ""

    logging.debug("project_lowerthan4: {}".format(project_lowerthan4))

    if project_lowerthan4:

        copyfile(projectFileName,
                 projectFileName.replace(".boris", "_old_version.boris"))

        msg = (
            "The project was updated to the current project version ({project_format_version}).\n\n"
            "The old file project was saved as {project_file_name}").format(
                project_format_version=project_format_version,
                project_file_name=projectFileName.replace(
                    ".boris", "_old_version.boris"))

    # if one file is present in player #1 -> set "media_info" key with value of media_file_info
    project_updated = False

    for obs in pj[OBSERVATIONS]:
        if pj[OBSERVATIONS][obs][TYPE] in [
                MEDIA
        ] and "media_info" not in pj[OBSERVATIONS][obs]:
            pj[OBSERVATIONS][obs]['media_info'] = {
                "length": {},
                "fps": {},
                "hasVideo": {},
                "hasAudio": {}
            }
            for player in [PLAYER1, PLAYER2]:
                # fix bug Anne Maijer 2017-07-17
                if pj[OBSERVATIONS][obs]["file"] == []:
                    pj[OBSERVATIONS][obs]["file"] = {"1": [], "2": []}

                for media_file_path in pj[OBSERVATIONS][obs]["file"][player]:
                    # FIX: ffmpeg path

                    ret, msg = utilities.check_ffmpeg_path()
                    if not ret:
                        return projectFileName, projectChanged, {
                            "error": "FFmpeg path not found"
                        }, ""
                    else:
                        ffmpeg_bin = msg

                    nframe, videoTime, videoDuration, fps, hasVideo, hasAudio = utilities.accurate_media_analysis(
                        ffmpeg_bin, media_file_path)

                    if videoDuration:
                        pj[OBSERVATIONS][obs]['media_info']["length"][
                            media_file_path] = videoDuration
                        pj[OBSERVATIONS][obs]['media_info']["fps"][
                            media_file_path] = fps
                        pj[OBSERVATIONS][obs]['media_info']["hasVideo"][
                            media_file_path] = hasVideo
                        pj[OBSERVATIONS][obs]['media_info']["hasAudio"][
                            media_file_path] = hasAudio
                        project_updated, projectChanged = True, True
                    else:  # file path not found
                        if ("media_file_info" in pj[OBSERVATIONS][obs] and len(
                                pj[OBSERVATIONS][obs]["media_file_info"]) == 1
                                and len(pj[OBSERVATIONS][obs]["file"][PLAYER1])
                                == 1
                                and len(pj[OBSERVATIONS][obs]["file"][PLAYER2])
                                == 0):
                            media_md5_key = list(pj[OBSERVATIONS][obs]
                                                 ["media_file_info"].keys())[0]
                            # duration
                            pj[OBSERVATIONS][obs]["media_info"] = {
                                "length": {
                                    media_file_path:
                                    pj[OBSERVATIONS][obs]["media_file_info"]
                                    [media_md5_key]["video_length"] / 1000
                                }
                            }
                            project_updated, projectChanged = True, True

                            # FPS
                            if "nframe" in pj[OBSERVATIONS][obs][
                                    "media_file_info"][media_md5_key]:
                                pj[OBSERVATIONS][obs]['media_info']['fps'] = {
                                    media_file_path:
                                    pj[OBSERVATIONS][obs]['media_file_info']
                                    [media_md5_key]['nframe'] /
                                    (pj[OBSERVATIONS][obs]['media_file_info']
                                     [media_md5_key]['video_length'] / 1000)
                                }
                            else:
                                pj[OBSERVATIONS][obs]['media_info']['fps'] = {
                                    media_file_path: 0
                                }

    if project_updated:
        msg = "The media files information was updated to the new project format."

    return projectFileName, projectChanged, pj, msg
Ejemplo n.º 5
0
 def test_media_does_not_exist(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/xxx")
     assert r == {'error': 'This file do not seem to be a media file'}
Ejemplo n.º 6
0
 def test_no_media(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/test.boris")
     assert r == {'error': 'This file do not seem to be a media file'}
Ejemplo n.º 7
0
 def test_media_ok(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/geese1.mp4")
     assert r == {'frames_number': 1548, 'duration_ms': Decimal('61920.00'),
                 'duration': Decimal('61.92'), 'fps': Decimal('25'),
                 'has_video': True, 'has_audio': True, 'bitrate': 901,
                 'resolution': '640x480'}
Ejemplo n.º 8
0
 def test_media_does_not_exist(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/xxx")
     assert "error" in r
Ejemplo n.º 9
0
 def test_no_media(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/test.boris")
     assert "error" in r
Ejemplo n.º 10
0
def open_project_json(projectFileName):
    """
    open project json

    Args:
        projectFileName (str): path of project

    Returns:
        str: project path
        bool: True if project changed
        dict: BORIS project
        str: message
    """

    logging.debug("open project: {0}".format(projectFileName))

    projectChanged = False
    msg = ""

    if not os.path.isfile(projectFileName):
        return projectFileName, projectChanged, {"error": "File {} not found".format(projectFileName)}, msg

    try:
        s = open(projectFileName, "r").read()
    except PermissionError:
        return projectFileName, projectChanged, {"error": "File {}: Permission denied".format(projectFileName)}, msg
    except Exception:
        return projectFileName, projectChanged, {"error": "Error on file {}: {}".format(projectFileName, sys.exc_info()[1])}, msg

    try:
        pj = json.loads(s)
    except json.decoder.JSONDecodeError:
        return projectFileName, projectChanged, {"error": "This project file seems corrupted"}, msg
    except Exception:
        return projectFileName, projectChanged, {"error": "This project file seems corruptedError on file {}: {}".format(projectFileName, sys.exc_info()[1])}, msg

    # transform time to decimal
    pj = utilities.convert_time_to_decimal(pj)

    # add coding_map key to old project files
    if "coding_map" not in pj:
        pj["coding_map"] = {}
        projectChanged = True

    # add subject description
    if "project_format_version" in pj:
        for idx in [x for x in pj[SUBJECTS]]:
            if "description" not in pj[SUBJECTS][idx]:
                pj[SUBJECTS][idx]["description"] = ""
                projectChanged = True

    # check if project file version is newer than current BORIS project file version
    if "project_format_version" in pj and Decimal(pj["project_format_version"]) > Decimal(project_format_version):
        return (
            projectFileName,
            projectChanged,
            {
                "error": (
                    "This project file was created with a more recent version of BORIS.<br>"
                    "You must update BORIS to <b>v. >= {}</b> to open this project"
                ).format(pj["project_format_version"])
            },
            msg,
        )

    # check if old version  v. 0 *.obs
    if "project_format_version" not in pj:

        # convert VIDEO, AUDIO -> MEDIA
        pj["project_format_version"] = project_format_version
        projectChanged = True

        for obs in [x for x in pj[OBSERVATIONS]]:

            # remove 'replace audio' key
            if "replace audio" in pj[OBSERVATIONS][obs]:
                del pj[OBSERVATIONS][obs]["replace audio"]

            if pj[OBSERVATIONS][obs][TYPE] in ["VIDEO", "AUDIO"]:
                pj[OBSERVATIONS][obs][TYPE] = MEDIA

            # convert old media list in new one
            if len(pj[OBSERVATIONS][obs][FILE]):
                d1 = {PLAYER1: [pj[OBSERVATIONS][obs][FILE][0]]}

            if len(pj[OBSERVATIONS][obs][FILE]) == 2:
                d1[PLAYER2] = [pj[OBSERVATIONS][obs][FILE][1]]

            pj[OBSERVATIONS][obs][FILE] = d1

        # convert VIDEO, AUDIO -> MEDIA
        for idx in [x for x in pj[SUBJECTS]]:
            key, name = pj[SUBJECTS][idx]
            pj[SUBJECTS][idx] = {"key": key, "name": name, "description": ""}

        msg = (
            "The project file was converted to the new format (v. {}) in use with your version of BORIS.<br>"
            "Choose a new file name for saving it."
        ).format(project_format_version)
        projectFileName = ""

    # update modifiers to JSON format

    # check if project format version < 4 (modifiers were str)
    project_lowerthan4 = False
    if "project_format_version" in pj and utilities.versiontuple(pj["project_format_version"]) < utilities.versiontuple("4.0"):
        for idx in pj[ETHOGRAM]:
            if pj[ETHOGRAM][idx]["modifiers"]:
                if isinstance(pj[ETHOGRAM][idx]["modifiers"], str):
                    project_lowerthan4 = True
                    modif_set_list = pj[ETHOGRAM][idx]["modifiers"].split("|")
                    modif_set_dict = {}
                    for modif_set in modif_set_list:
                        modif_set_dict[str(len(modif_set_dict))] = {"name": "", "type": SINGLE_SELECTION, "values": modif_set.split(",")}
                    pj[ETHOGRAM][idx]["modifiers"] = dict(modif_set_dict)
            else:
                pj[ETHOGRAM][idx]["modifiers"] = {}

        if not project_lowerthan4:
            msg = "The project version was updated from {} to {}".format(pj["project_format_version"], project_format_version)
            pj["project_format_version"] = project_format_version
            projectChanged = True

    # add category key if not found
    for idx in pj[ETHOGRAM]:
        if "category" not in pj[ETHOGRAM][idx]:
            pj[ETHOGRAM][idx]["category"] = ""

    # if one file is present in player #1 -> set "media_info" key with value of media_file_info
    for obs in pj[OBSERVATIONS]:
        if pj[OBSERVATIONS][obs][TYPE] in [MEDIA] and MEDIA_INFO not in pj[OBSERVATIONS][obs]:
            pj[OBSERVATIONS][obs][MEDIA_INFO] = {LENGTH: {}, "fps": {}, "hasVideo": {}, "hasAudio": {}}
            for player in [PLAYER1, PLAYER2]:
                # fix bug Anne Maijer 2017-07-17
                if pj[OBSERVATIONS][obs][FILE] == []:
                    pj[OBSERVATIONS][obs][FILE] = {"1": [], "2": []}

                for media_file_path in pj[OBSERVATIONS][obs]["file"][player]:
                    # FIX: ffmpeg path
                    ret, msg = utilities.check_ffmpeg_path()
                    if not ret:
                        return projectFileName, projectChanged, {"error": "FFmpeg path not found"}, ""
                    else:
                        ffmpeg_bin = msg

                    r = utilities.accurate_media_analysis(ffmpeg_bin, media_file_path)

                    if "duration" in r and r["duration"]:
                        pj[OBSERVATIONS][obs][MEDIA_INFO][LENGTH][media_file_path] = float(r["duration"])
                        pj[OBSERVATIONS][obs][MEDIA_INFO][FPS][media_file_path] = float(r["fps"])
                        pj[OBSERVATIONS][obs][MEDIA_INFO]["hasVideo"][media_file_path] = r["has_video"]
                        pj[OBSERVATIONS][obs][MEDIA_INFO]["hasAudio"][media_file_path] = r["has_audio"]
                        project_updated, projectChanged = True, True
                    else:  # file path not found
                        if (
                            "media_file_info" in pj[OBSERVATIONS][obs] and
                            len(pj[OBSERVATIONS][obs]["media_file_info"]) == 1 and
                            len(pj[OBSERVATIONS][obs][FILE][PLAYER1]) == 1 and
                            len(pj[OBSERVATIONS][obs][FILE][PLAYER2]) == 0
                        ):
                            media_md5_key = list(pj[OBSERVATIONS][obs]["media_file_info"].keys())[0]
                            # duration
                            pj[OBSERVATIONS][obs][MEDIA_INFO] = {
                                LENGTH: {media_file_path: pj[OBSERVATIONS][obs]["media_file_info"][media_md5_key]["video_length"] / 1000}
                            }
                            projectChanged = True

                            # FPS
                            if "nframe" in pj[OBSERVATIONS][obs]["media_file_info"][media_md5_key]:
                                pj[OBSERVATIONS][obs][MEDIA_INFO][FPS] = {
                                    media_file_path: pj[OBSERVATIONS][obs]["media_file_info"][media_md5_key]["nframe"] /
                                    (pj[OBSERVATIONS][obs]["media_file_info"][media_md5_key]["video_length"] / 1000)
                                }
                            else:
                                pj[OBSERVATIONS][obs][MEDIA_INFO][FPS] = {media_file_path: 0}

    # update project to v.7 for time offset second player
    project_lowerthan7 = False
    for obs in pj[OBSERVATIONS]:
        if "time offset second player" in pj[OBSERVATIONS][obs]:
            if MEDIA_INFO not in pj[OBSERVATIONS][obs]:
                pj[OBSERVATIONS][obs][MEDIA_INFO] = {}
            if "offset" not in pj[OBSERVATIONS][obs][MEDIA_INFO]:
                pj[OBSERVATIONS][obs][MEDIA_INFO]["offset"] = {}
            for player in pj[OBSERVATIONS][obs][FILE]:
                pj[OBSERVATIONS][obs][MEDIA_INFO]["offset"][player] = 0.0
            if pj[OBSERVATIONS][obs]["time offset second player"]:
                pj[OBSERVATIONS][obs][MEDIA_INFO]["offset"]["2"] = float(pj[OBSERVATIONS][obs]["time offset second player"])

            del pj[OBSERVATIONS][obs]["time offset second player"]
            project_lowerthan7 = True

            msg = (
                "The project file was converted to the new format (v. {project_version}) in use with your version of BORIS.<br>"
                "Please note that this new version will NOT be compatible with previous BORIS versions (&lt; v. {project_version}).<br>"
            ).format(project_version=project_format_version)

            projectChanged = True


    if project_lowerthan7:

        msg = (
            "The project was updated to the current project version ({project_format_version})."
        ).format(project_format_version=project_format_version)

        try:
            copyfile(projectFileName, projectFileName.replace(".boris", ".v{}.boris".format(pj["project_format_version"])))
            msg += "\n\nThe old file project was saved as {}".format(projectFileName.replace(".boris", ".v{}.boris".format(pj["project_format_version"])))
        except Exception:
            pass

        pj["project_format_version"] = project_format_version

    return projectFileName, projectChanged, pj, msg
Ejemplo n.º 11
0
 def test_media_does_not_exist(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/xxx")
     assert r == {'error': 'This file do not seem to be a media file'}
Ejemplo n.º 12
0
 def test_no_media(self):
     r = utilities.accurate_media_analysis("ffmpeg", "files/test.boris")
     assert r == {'error': 'This file do not seem to be a media file'}