Reaper-Tools

Audiokinetic Reaper Tools Repository
Log | Files | Refs

OpenAssociatedReaperProject_Script.lua (5584B)


      1 --[[
      2   @description OpenAssociatedReaperProject_Script
      3   @author Audiokinetic
      4   @noindex
      5   @provides
      6     [nomain] . https://raw.githubusercontent.com/audiokinetic/Reaper-Tools/$commit/OpenAssociatedReaperProject/OpenAssociatedReaperProject_Script.lua
      7   @about
      8     The script opens up the associated REAPER project of a  wav file based on his metadata.
      9   @license
     10     Copyright (c) 2023 AUDIOKINETIC Inc.
     11 
     12     The script in this file is licensed to use under the license available at:
     13     https://raw.githubusercontent.com/audiokinetic/Reaper-Tools/main/License.txt (the "License").
     14     You may not use this file except in compliance with the License.
     15 
     16     Unless required by applicable law or agreed to in writing, software distributed
     17     under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
     18     CONDITIONS OF ANY KIND, either express or implied.  See the License for the
     19     specific language governing permissions and limitations under the License.
     20 ]]--
     21 
     22 info = debug.getinfo(1,'S')
     23 scriptPath = info.source:match[[^@?(.*[\/])[^\/]-$]]
     24 local utils = dofile(scriptPath.."Utilities.lua")
     25 
     26 local tempProject, _ = reaper.EnumProjects( -1, "" )
     27 
     28 local firstTrack = reaper.GetTrack(utils.CURRENT_PROJECT, 0)
     29 
     30 if not firstTrack then
     31   reaper.ShowMessageBox("No audio file sent to REAPER!", "Open Associated REAPER Project: Failed", utils.OK_MESSAGE_BOX)
     32   return
     33 end
     34 
     35 local mediaItemCount = reaper.CountTrackMediaItems(firstTrack)
     36 local mediaItem = reaper.GetTrackMediaItem(firstTrack, 0)
     37 local mediaItemTake = reaper.GetActiveTake(mediaItem)
     38 local pcmSource = reaper.GetMediaItemTake_Source(mediaItemTake)
     39 local filePath = reaper.GetMediaSourceFileName(pcmSource)
     40 
     41 if not reaper.file_exists(filePath) then
     42   reaper.ShowMessageBox("Unable to locate file `" .. filePath .. "`", "Open Associated REAPER Project: Failed", utils.OK_MESSAGE_BOX)
     43   return
     44 end
     45 
     46 -- Read data from wav header --
     47 local pcmSource = reaper.PCM_Source_CreateFromFile(filePath)
     48 local projectName = utils.getMetadata(pcmSource, {"IXML:PROJECT", "IXML:Project", "IXML:project", "INFO:INAME"})
     49 local startOffset = utils.getMetadata(pcmSource, {"Generic:StartOffset"})
     50 local trackName = utils.getMetadata(pcmSource, {"IXML:USER:trackName", "IXML:USER:TRACKNAME", "IXML:USER:TrackName", "IXML:USER:trackname"})
     51 
     52 if startOffset == nil then
     53   startOffset = "0:00.000"
     54 end
     55 
     56 if not projectName then
     57   reaper.ShowMessageBox("IXML:PROJECT header missing or empty in selected file. The script expects the IXML:PROJECT header to contain the associated project name. Make sure 'Embed title/date/time if not provided' and 'Embed start offset' option in the Project Render Metadata are enabled.", "Open Associated REAPER Project: Failed", utils.OK_MESSAGE_BOX)
     58   return
     59 end
     60 
     61 local projectDirectory = utils.getParentDirectory(filePath)
     62 
     63 local info = debug.getinfo(1, 'S')
     64 local scriptPath = info.source:match[[^@?(.*[\/])[^\/]-$]]
     65 local reaperProjectsRootPath = scriptPath.."ReaperProjectsRoot.txt"
     66 local file, err = io.open(reaperProjectsRootPath, "r")
     67 local reaperProjectsRoot = os.getenv("REAPERPROJECTSROOT")
     68 if file and not reaperProjectsRoot then
     69   reaperProjectsRoot = file:read()
     70   file:close()
     71 end
     72 
     73 local function findRppFile(dir, rppFile)
     74   local i = 0
     75   local file = reaper.EnumerateFiles(dir, i)
     76   repeat
     77     if file ~= nil and file == rppFile then
     78       return dir .. utils.SEPARATOR_CHAR .. file
     79     end
     80     i = i + 1
     81     file = reaper.EnumerateFiles(dir, i)
     82   until file == nil
     83 
     84   i = 0
     85   local subDir = reaper.EnumerateSubdirectories(dir, i)
     86   repeat
     87     if subDir ~= nil then
     88       local ret = findRppFile(dir .. utils.SEPARATOR_CHAR .. subDir, rppFile)
     89       if ret ~= nil then
     90         return ret
     91       end
     92       i = i + 1
     93       subDir = reaper.EnumerateSubdirectories(dir, i)
     94     end
     95   until subDir == nil
     96   return nil
     97 end
     98 
     99 local projectPath = findRppFile(reaperProjectsRoot, projectName .. ".rpp")
    100 
    101 if not projectPath then
    102   projectName = string.gsub(projectName, "\n", " ")
    103   reaper.ShowMessageBox("Unable to locate project `" .. projectName .. "` in `" .. reaperProjectsRoot .. "`", "Open Associated REAPER Project: Failed", utils.OK_MESSAGE_BOX)
    104   return
    105 end
    106 
    107 -- Open project and set cursor to start offset --
    108 reaper.Main_OnCommand(41929, 0) -- opens new project tab
    109 reaper.Main_openProject("noprompt:" .. projectPath)
    110 
    111 local project, _ = reaper.EnumProjects( -1, "" )
    112 
    113 local markersAndRegions, _, _ = reaper.CountProjectMarkers(utils.CURRENT_PROJECT)
    114 
    115 local buf = ""
    116 for i = 0, markersAndRegions - 1 do
    117   local _, isRegion, currentRegionPos, _, currentRegion, index, _ = reaper.EnumProjectMarkers3(0, i)
    118 
    119   if isRegion and reaper.format_timestr(currentRegionPos, buf) == startOffset then
    120     reaper.GoToRegion(0, index, true)
    121     reaper.adjustZoom(100, 1, true, -1)
    122     break
    123   end
    124 end
    125 
    126 local trackView = reaper.JS_Window_FindChildByID(reaper.GetMainHwnd(), utils.TRACK_VIEW_ID)
    127 
    128 reaper.Main_OnCommand(40297,0) -- deselect all tracks
    129 
    130 if trackName then
    131   for i = 0, reaper.CountTracks() - 1 do
    132     local currentTrack = reaper.GetTrack(utils.CURRENT_PROJECT, i)
    133     local _, currentTrackName = reaper.GetTrackName(currentTrack)
    134 
    135     if currentTrackName == trackName then
    136       reaper.SetTrackSelected(currentTrack, true)
    137 
    138       -- Get Y postion of track and then scroll to it
    139       local yPosition = reaper.GetMediaTrackInfo_Value(currentTrack, "I_TCPY")
    140       reaper.JS_Window_SetScrollPos(trackView, "v", yPosition)
    141       break
    142     end
    143   end
    144 end
    145 
    146 reaper.SelectProjectInstance(tempProject)
    147 reaper.Main_OnCommand(40860,0) -- close current project tab
    148 reaper.SelectProjectInstance(project)