diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java
index d14ba09c2..64f7dad85 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/dao/CommonGBChannelMapper.java
@@ -550,52 +550,4 @@ public interface CommonGBChannelMapper {
                                                        @Param("channelType") Integer channelType, @Param("online") Boolean online,
                                                        @Param("hasLink") Boolean hasLink);
 
-    @Select("<script>" +
-            " select " +
-            "    wdc.id as gb_id,\n" +
-            "    wdc.device_db_id as gb_device_db_id,\n" +
-            "    wdc.stream_push_id,\n" +
-            "    wdc.stream_proxy_id,\n" +
-            "    wdc.create_time,\n" +
-            "    wdc.update_time,\n" +
-            "    wdc.record_plan_id,\n" +
-            "    coalesce( wdc.gb_device_id, wdc.device_id) as gb_device_id,\n" +
-            "    coalesce( wdc.gb_name, wdc.name) as gb_name,\n" +
-            "    coalesce( wdc.gb_manufacturer, wdc.manufacturer) as gb_manufacturer,\n" +
-            "    coalesce( wdc.gb_model, wdc.model) as gb_model,\n" +
-            "    coalesce( wdc.gb_owner, wdc.owner) as gb_owner,\n" +
-            "    coalesce( wdc.gb_civil_code, wdc.civil_code) as gb_civil_code,\n" +
-            "    coalesce( wdc.gb_block, wdc.block) as gb_block,\n" +
-            "    coalesce( wdc.gb_address, wdc.address) as gb_address,\n" +
-            "    coalesce( wdc.gb_parental, wdc.parental) as gb_parental,\n" +
-            "    coalesce( wdc.gb_parent_id, wdc.parent_id) as gb_parent_id,\n" +
-            "    coalesce( wdc.gb_safety_way, wdc.safety_way) as gb_safety_way,\n" +
-            "    coalesce( wdc.gb_register_way, wdc.register_way) as gb_register_way,\n" +
-            "    coalesce( wdc.gb_cert_num, wdc.cert_num) as gb_cert_num,\n" +
-            "    coalesce( wdc.gb_certifiable, wdc.certifiable) as gb_certifiable,\n" +
-            "    coalesce( wdc.gb_err_code, wdc.err_code) as gb_err_code,\n" +
-            "    coalesce( wdc.gb_end_time, wdc.end_time) as gb_end_time,\n" +
-            "    coalesce( wdc.gb_secrecy, wdc.secrecy) as gb_secrecy,\n" +
-            "    coalesce( wdc.gb_ip_address, wdc.ip_address) as gb_ip_address,\n" +
-            "    coalesce( wdc.gb_port, wdc.port) as gb_port,\n" +
-            "    coalesce( wdc.gb_password, wdc.password) as gb_password,\n" +
-            "    coalesce( wdc.gb_status, wdc.status) as gb_status,\n" +
-            "    coalesce( wdc.gb_longitude, wdc.longitude) as gb_longitude,\n" +
-            "    coalesce( wdc.gb_latitude, wdc.latitude) as gb_latitude,\n" +
-            "    coalesce( wdc.gb_ptz_type, wdc.ptz_type) as gb_ptz_type,\n" +
-            "    coalesce( wdc.gb_position_type, wdc.position_type) as gb_position_type,\n" +
-            "    coalesce( wdc.gb_room_type, wdc.room_type) as gb_room_type,\n" +
-            "    coalesce( wdc.gb_use_type, wdc.use_type) as gb_use_type,\n" +
-            "    coalesce( wdc.gb_supply_light_type, wdc.supply_light_type) as gb_supply_light_type,\n" +
-            "    coalesce( wdc.gb_direction_type, wdc.direction_type) as gb_direction_type,\n" +
-            "    coalesce( wdc.gb_resolution, wdc.resolution) as gb_resolution,\n" +
-            "    coalesce( wdc.gb_business_group_id, wdc.business_group_id) as gb_business_group_id,\n" +
-            "    coalesce( wdc.gb_download_speed, wdc.download_speed) as gb_download_speed,\n" +
-            "    coalesce( wdc.gb_svc_space_support_mod, wdc.svc_space_support_mod) as gb_svc_space_support_mod,\n" +
-            "    coalesce( wdc.gb_svc_time_support_mode, wdc.svc_time_support_mode) as gb_svc_time_support_mode \n" +
-            " from wvp_device_channel wdc" +
-            " where wdc.record_plan_id in " +
-            " <foreach collection='planIdList'  item='item'  open='(' separator=',' close=')' > #{item}</foreach>" +
-            "</script>")
-    List<CommonGBChannel> queryForRecordPlan(List<Integer> planIdList);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/service/IRecordPlanService.java b/src/main/java/com/genersoft/iot/vmp/service/IRecordPlanService.java
index abec8e0cb..f3b34912c 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/IRecordPlanService.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/IRecordPlanService.java
@@ -27,5 +27,5 @@ public interface IRecordPlanService {
 
     void cleanAll(Integer planId);
 
-    boolean recording(String app, String stream);
+    Integer recording(String app, String stream);
 }
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
index 0959c7843..fcb7570fb 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/MediaServiceImpl.java
@@ -209,7 +209,7 @@ public class MediaServiceImpl implements IMediaService {
     @Override
     public boolean closeStreamOnNoneReader(String mediaServerId, String app, String stream, String schema) {
         boolean result = false;
-        if (recordPlanService.recording(app, stream)) {
+        if (recordPlanService.recording(app, stream) != null) {
             return false;
         }
         // 国标类型的流
diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/RecordPlanServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/RecordPlanServiceImpl.java
index 4bcc945a0..ac146e867 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/RecordPlanServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/RecordPlanServiceImpl.java
@@ -17,6 +17,7 @@ import com.genersoft.iot.vmp.utils.DateUtil;
 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.google.common.base.Joiner;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
@@ -27,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 @Service
 @Slf4j
@@ -53,63 +55,94 @@ public class RecordPlanServiceImpl implements IRecordPlanService {
     @EventListener
     public void onApplicationEvent(MediaDepartureEvent event) {
         // 流断开,检查是否还处于录像状态, 如果是则继续录像
-        if (recording(event.getApp(), event.getStream())) {
-            // 重新拉起
-
+        Integer channelId = recording(event.getApp(), event.getStream());
+        if(channelId == null) {
+            return;
         }
+        // 重新拉起
+        CommonGBChannel channel = channelMapper.queryById(channelId);
+        if (channel == null) {
+            log.warn("[录制计划] 流离开时拉起需要录像的流时, 发现通道不存在, id: {}", channelId);
+            return;
+        }
+        // 开启点播,
+        channelPlayService.play(channel, null, ((code, msg, streamInfo) -> {
+            if (code == InviteErrorCode.SUCCESS.getCode() && streamInfo != null) {
+                log.info("[录像] 流离开时拉起需要录像的流, 开启成功, 通道ID: {}", channel.getGbId());
+                recordStreamMap.put(channel.getGbId(), streamInfo);
+            } else {
+                recordStreamMap.remove(channelId);
+                log.info("[录像] 流离开时拉起需要录像的流, 开启失败, 十分钟后重试,  通道ID: {}", channel.getGbId());
+            }
+        }));
     }
 
     Map<Integer, StreamInfo> recordStreamMap = new HashMap<>();
 
-    @Scheduled(cron = "0 */30 * * * *")
+//    @Scheduled(cron = "0 */30 * * * *")
+    @Scheduled(fixedRate = 10, timeUnit = TimeUnit.MINUTES)
     public void execution() {
-        // 执行计划
+        log.info("[录制计划] 执行");
+        // 查询现在需要录像的通道Id
+        List<Integer> startChannelIdList = queryCurrentChannelRecord();
 
-        // 获取当前时间在一周内的序号
-        LocalDateTime now = LocalDateTime.now();
-        int week = now.getDayOfWeek().getValue();
-        int index = now.getHour() * 2 + (now.getMinute() > 30?1:0);
-        // 查询startTime等于现在的, 开始录像
-        List<Integer> startPlanList = recordPlanMapper.queryStart(week, index);
-
-        Map<Integer, StreamInfo> channelMapWithoutRecord = new HashMap<>();
-        if (startPlanList.isEmpty()) {
-            // 停止所有正在录像的
-            if(recordStreamMap.isEmpty()) {
-                // 暂无录像任务
-                return;
-            }else {
-                channelMapWithoutRecord.putAll(recordStreamMap);
+        if (startChannelIdList.isEmpty()) {
+            // 当前没有录像任务, 如果存在旧的正在录像的就移除
+            if(!recordStreamMap.isEmpty()) {
+                stopStreams(recordStreamMap.keySet(), recordStreamMap);
                 recordStreamMap.clear();
             }
         }else {
-            channelMapWithoutRecord.putAll(recordStreamMap);
-            // 获取所有的关联的通道
-            List<CommonGBChannel> channelList = channelMapper.queryForRecordPlan(startPlanList);
-            if (channelList.isEmpty()) {
-                recordStreamMap.clear();
-            }else {
-                // 查找是否已经开启录像, 如果没有则开启录像
-                for (CommonGBChannel channel : channelList) {
-                    if (recordStreamMap.get(channel.getGbId()) != null) {
-                        channelMapWithoutRecord.remove(channel.getGbId());
-                    }else {
+            // 当前存在录像任务, 获取正在录像中存在但是当前录制列表不存在的内容,进行停止; 获取正在录像中没有但是当前需录制的列表中存在的进行开启.
+            Set<Integer> recordStreamSet = new HashSet<>(recordStreamMap.keySet());
+            startChannelIdList.forEach(recordStreamSet::remove);
+            if (!recordStreamSet.isEmpty()) {
+                // 正在录像中存在但是当前录制列表不存在的内容,进行停止;
+                stopStreams(recordStreamSet, recordStreamMap);
+            }
+
+            // 移除startChannelIdList中已经在录像的部分, 剩下的都是需要新添加的(正在录像中没有但是当前需录制的列表中存在的进行开启)
+            recordStreamMap.keySet().forEach(startChannelIdList::remove);
+            if (!startChannelIdList.isEmpty()) {
+                // 获取所有的关联的通道
+                List<CommonGBChannel> channelList = channelMapper.queryByIds(startChannelIdList);
+                if (!channelList.isEmpty()) {
+                    // 查找是否已经开启录像, 如果没有则开启录像
+                    for (CommonGBChannel channel : channelList) {
                         // 开启点播,
                         channelPlayService.play(channel, null, ((code, msg, streamInfo) -> {
                             if (code == InviteErrorCode.SUCCESS.getCode() && streamInfo != null) {
                                 log.info("[录像] 开启成功, 通道ID: {}", channel.getGbId());
                                 recordStreamMap.put(channel.getGbId(), streamInfo);
-                                channelMapWithoutRecord.remove(channel.getGbId(), streamInfo);
+                            } else {
+                                log.info("[录像] 开启失败, 十分钟后重试,  通道ID: {}", channel.getGbId());
                             }
                         }));
                     }
+                } else {
+                    log.error("[录制计划] 数据异常, 这些关联的通道已经不存在了: {}", Joiner.on(",").join(startChannelIdList));
                 }
             }
         }
-        // 结束录像
-        if(!channelMapWithoutRecord.isEmpty()) {
-            for (Integer channelId : channelMapWithoutRecord.keySet()) {
-                StreamInfo streamInfo = channelMapWithoutRecord.get(channelId);
+    }
+
+    /**
+     * 获取当前时间段应该录像的通道Id列表
+     */
+    private List<Integer> queryCurrentChannelRecord(){
+        // 获取当前时间在一周内的序号, 数据库存储的从第几个30分钟开始, 0-47, 包括首尾
+        LocalDateTime now = LocalDateTime.now();
+        int week = now.getDayOfWeek().getValue();
+        int index = now.getHour() * 2 + (now.getMinute() > 30?1:0);
+
+        // 查询现在需要录像的通道Id
+        return recordPlanMapper.queryRecordIng(week, index);
+    }
+
+    private void stopStreams(Collection<Integer> channelIds, Map<Integer, StreamInfo> recordStreamMap) {
+        for (Integer channelId : channelIds) {
+            try {
+                StreamInfo streamInfo = recordStreamMap.get(channelId);
                 if (streamInfo == null) {
                     continue;
                 }
@@ -117,23 +150,25 @@ public class RecordPlanServiceImpl implements IRecordPlanService {
                 MediaInfo mediaInfo = mediaServerService.getMediaInfo(streamInfo.getMediaServer(), streamInfo.getApp(), streamInfo.getStream());
                 if (mediaInfo.getReaderCount() == null ||  mediaInfo.getReaderCount() == 0) {
                     mediaServerService.closeStreams(streamInfo.getMediaServer(), streamInfo.getApp(), streamInfo.getStream());
-                    log.info("[录像] 停止, 通道ID: {}", channelId);
+                    log.info("[录制计划] 停止, 通道ID: {}", channelId);
                 }
+            }catch (Exception e) {
+                log.error("[录制计划] 停止时异常", e);
+            }finally {
+                recordStreamMap.remove(channelId);
             }
         }
     }
 
-    // 系统启动时
-
-
     @Override
-    public boolean recording(String app, String stream) {
-        for (StreamInfo streamInfo : recordStreamMap.values()) {
-            if (streamInfo.getApp().equals(app) && streamInfo.getStream().equals(stream)) {
-                return true;
+    public Integer recording(String app, String stream) {
+        for (Integer channelId : recordStreamMap.keySet()) {
+            StreamInfo streamInfo = recordStreamMap.get(channelId);
+            if (streamInfo != null && streamInfo.getApp().equals(app) && streamInfo.getStream().equals(stream)) {
+                return channelId;
             }
         }
-        return false;
+        return null;
     }
 
     @Override
@@ -226,7 +261,12 @@ public class RecordPlanServiceImpl implements IRecordPlanService {
         }else {
             channelMapper.addRecordPlan(channelIds, planId);
         }
-        // TODO  更新录像队列
+        // 查看当前的待录制列表是否变化,如果变化,则调用录制计划马上开始录制
+        List<Integer> currentChannelRecord = queryCurrentChannelRecord();
+        recordStreamMap.keySet().forEach(currentChannelRecord::remove);
+        if (!currentChannelRecord.isEmpty()) {
+            execution();
+        }
     }
 
     @Override
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/RecordPlanMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/RecordPlanMapper.java
index e9304df05..ae0649aa2 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/dao/RecordPlanMapper.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/RecordPlanMapper.java
@@ -59,6 +59,9 @@ public interface RecordPlanMapper {
     @Delete("DELETE FROM wvp_record_plan_item WHERE plan_id = #{planId}")
     void cleanItems(@Param("planId") Integer planId);
 
-    @Select("select plan_id from wvp_record_plan_item where  week_day = #{week} and start &gt;= #{index} and stop &lt;= #{index} group by plan_id")
-    List<Integer> queryStart(@Param("week") int week, @Param("index") int index);
+    @Select(" <script>" +
+            " select wdc.id from wvp_device_channel wdc left join wvp_record_plan_item wrpi on wrpi.plan_id = wdc.record_plan_id " +
+            " where  wrpi.week_day = #{week} and wrpi.start &lt;= #{index} and stop &gt;= #{index} group by wdc.id" +
+            " </script>")
+    List<Integer> queryRecordIng(@Param("week") int week, @Param("index") int index);
 }